Skip to content

Commit 46b86c0

Browse files
committed
update
1 parent 9155f90 commit 46b86c0

File tree

12 files changed

+391
-1
lines changed

12 files changed

+391
-1
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

.github/workflows/pipeline.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: PIPELINE
2+
3+
on:
4+
push:
5+
branches:
6+
- 'master'
7+
workflow_dispatch:
8+
9+
jobs:
10+
bump:
11+
uses: UnterrainerInformatik/bump-semver-workflow/.github/workflows/workflow.yml@master
12+
13+
build:
14+
name: Build and publish to Maven Central 🚀
15+
needs: bump
16+
uses: UnterrainerInformatik/maven-central-workflow/.github/workflows/workflow.yml@master
17+
with:
18+
major_version: ${{ needs.bump.outputs.major_version }}
19+
minor_version: ${{ needs.bump.outputs.minor_version }}
20+
build_version: ${{ needs.bump.outputs.build_version }}
21+
maven_profiles: release-to-sonatype
22+
maven_args: -Dmaven.test.skip=true
23+
secrets:
24+
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
25+
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
26+
GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }}
27+
GPG_OWNERTRUST: ${{ secrets.GPG_OWNERTRUST }}
28+
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

.gitignore

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,14 @@
2121

2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
24-
replay_pid*
24+
/target/
25+
26+
src/main/java/info/unterrainer/commons/jreutils/Information.java
27+
28+
.settings/
29+
30+
.classpath
31+
32+
bin/
33+
34+
dependency-reduced-pom.xml

.project

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>websocket-client</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.m2e.core.maven2Builder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>org.eclipse.m2e.core.maven2Nature</nature>
22+
</natures>
23+
</projectDescription>

Information.template

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package @package@;
2+
3+
public class Information {
4+
public static final String name = "@name@";
5+
public static final String buildTime = "@buildTime@";
6+
public static final String pomVersion = "@pomVersion@";
7+
}

pom.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
5+
<parent>
6+
<groupId>info.unterrainer.commons</groupId>
7+
<artifactId>parent-pom</artifactId>
8+
<version>1.0.2</version>
9+
</parent>
10+
11+
<modelVersion>4.0.0</modelVersion>
12+
<artifactId>websocket-client</artifactId>
13+
<version>1.0.0</version>
14+
<name>WebsocketClient</name>
15+
<packaging>jar</packaging>
16+
17+
<properties>
18+
<mainclass>info.unterrainer.commons.websocketclient.WebsocketClient</mainclass>
19+
<name>Websocket-Client</name>
20+
<package-path>info/unterrainer/commons/websocketclient</package-path>
21+
<packg-string>info.unterrainer.commons.websocketclient</packg-string>
22+
</properties>
23+
24+
<dependencies>
25+
<dependency>
26+
<groupId>info.unterrainer.commons</groupId>
27+
<artifactId>oauth-token-manager</artifactId>
28+
<version>1.0.7</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>javax.websocket</groupId>
32+
<artifactId>javax.websocket-api</artifactId>
33+
<version>1.1</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.glassfish.tyrus</groupId>
37+
<artifactId>tyrus-client</artifactId>
38+
<version>2.1.3</version>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.glassfish.tyrus</groupId>
42+
<artifactId>tyrus-container-grizzly-client</artifactId>
43+
<version>2.1.3</version>
44+
</dependency>
45+
46+
</dependencies>
47+
48+
</project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package info.unterrainer.websocketclient;
2+
3+
public class SendingMessageWebsocketException extends RuntimeException {
4+
5+
public SendingMessageWebsocketException() {
6+
super();
7+
}
8+
9+
public SendingMessageWebsocketException(String message) {
10+
super(message);
11+
}
12+
13+
public SendingMessageWebsocketException(Throwable cause) {
14+
super(cause);
15+
}
16+
17+
public SendingMessageWebsocketException(String message, Throwable cause) {
18+
super(message, cause);
19+
}
20+
21+
private static final long serialVersionUID = 661400825771800217L;
22+
23+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package info.unterrainer.websocketclient;
2+
3+
import java.io.IOException;
4+
import java.net.URI;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.concurrent.CompletableFuture;
8+
import java.util.function.Consumer;
9+
10+
import org.glassfish.tyrus.client.ClientManager;
11+
12+
import info.unterrainer.oauthtokenmanager.LocalOauthTokens;
13+
import info.unterrainer.oauthtokenmanager.OauthTokenManager;
14+
import jakarta.websocket.ClientEndpointConfig;
15+
import jakarta.websocket.ClientEndpointConfig.Builder;
16+
import jakarta.websocket.CloseReason;
17+
import jakarta.websocket.Session;
18+
import lombok.Data;
19+
import lombok.EqualsAndHashCode;
20+
import lombok.RequiredArgsConstructor;
21+
import lombok.experimental.SuperBuilder;
22+
import lombok.extern.slf4j.Slf4j;
23+
24+
@Slf4j
25+
@Data
26+
@RequiredArgsConstructor
27+
@SuperBuilder(toBuilder = true)
28+
@EqualsAndHashCode()
29+
public class WebsocketConnection implements AutoCloseable {
30+
31+
private final String host;
32+
final Consumer<Session> onOpenHandler;
33+
final Consumer<String> onMessageHandler;
34+
final Consumer<Session> onCloseHandler;
35+
final Consumer<Throwable> onErrorHandler;
36+
final String keycloakHost;
37+
final String keycloakClient;
38+
final String keycloakClientSecret;
39+
final String keycloakUser;
40+
final String keycloakPassword;
41+
42+
private WebsocketEndpoints endpoints;
43+
44+
final CompletableFuture<Session> sessionReady = new CompletableFuture<>();
45+
46+
public Session awaitOpen() {
47+
try {
48+
return sessionReady.get();
49+
} catch (Exception e) {
50+
throw new IllegalStateException("WebSocket did not open in time.", e);
51+
}
52+
}
53+
54+
public void send(String message) {
55+
Session s = awaitOpen();
56+
try {
57+
s.getBasicRemote().sendText(message);
58+
} catch (Exception e) {
59+
log.error("Error sending message: ", e);
60+
throw new SendingMessageWebsocketException(String.format("Failed to send message [%s].", message), e);
61+
}
62+
log.debug("Sent message: " + message);
63+
}
64+
65+
@Override
66+
public void close() {
67+
Session s = awaitOpen();
68+
try {
69+
s.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Normal closure"));
70+
} catch (IOException e) {
71+
log.error("Error closing session.", e);
72+
}
73+
}
74+
75+
public void establish() {
76+
String accessToken = null;
77+
ClientManager container = ClientManager.createClient();
78+
endpoints = new WebsocketEndpoints(this);
79+
Builder c = ClientEndpointConfig.Builder.create();
80+
81+
if (keycloakHost != null) {
82+
OauthTokenManager tokenManager = new OauthTokenManager(keycloakHost, keycloakClient);
83+
LocalOauthTokens tokens = tokenManager.getTokensFromCredentials(keycloakClient, keycloakUser,
84+
keycloakPassword);
85+
accessToken = tokens.getAccessToken();
86+
String at = "Bearer " + accessToken;
87+
88+
c.configurator(new ClientEndpointConfig.Configurator() {
89+
@Override
90+
public void beforeRequest(Map<String, List<String>> headers) {
91+
headers.put("Authorization", List.of(at));
92+
}
93+
});
94+
}
95+
ClientEndpointConfig config = c.build();
96+
97+
try {
98+
container.connectToServer(endpoints, config, URI.create(host));
99+
} catch (Exception e) {
100+
log.error("Error connecting to WebSocket server: ", e);
101+
return;
102+
}
103+
log.info("WebSocket client connected to: {}", host);
104+
}
105+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package info.unterrainer.websocketclient;
2+
3+
import jakarta.websocket.CloseReason;
4+
import jakarta.websocket.Endpoint;
5+
import jakarta.websocket.EndpointConfig;
6+
import jakarta.websocket.Session;
7+
import lombok.extern.slf4j.Slf4j;
8+
9+
@Slf4j
10+
public class WebsocketEndpoints extends Endpoint {
11+
12+
private final WebsocketConnection client;
13+
14+
public WebsocketEndpoints(WebsocketConnection client) {
15+
this.client = client;
16+
}
17+
18+
@Override
19+
public void onOpen(Session session, EndpointConfig config) {
20+
client.sessionReady.complete(session);
21+
log.info("Connected to server");
22+
23+
// onOpen-Handler
24+
if (client.onOpenHandler != null) {
25+
try {
26+
client.onOpenHandler.accept(session);
27+
} catch (Exception e) {
28+
log.error("Error executing onOpen handler: ", e);
29+
}
30+
}
31+
32+
// onMessage-Handler
33+
session.addMessageHandler(String.class, message -> {
34+
log.debug("Received message: " + message);
35+
client.awaitOpen();
36+
if (client.onMessageHandler != null) {
37+
try {
38+
client.onMessageHandler.accept(message);
39+
} catch (Exception e) {
40+
log.error("Error executing onMessage handler: ", e);
41+
}
42+
}
43+
});
44+
}
45+
46+
@Override
47+
public void onClose(Session session, CloseReason closeReason) {
48+
Session s = client.awaitOpen();
49+
log.info("Disconnected from server: {}", closeReason);
50+
if (client.onCloseHandler != null) {
51+
try {
52+
client.onCloseHandler.accept(s);
53+
} catch (Exception e) {
54+
log.error("Error executing onClose handler: ", e);
55+
}
56+
}
57+
58+
try {
59+
s.close();
60+
} catch (Exception e) {
61+
log.error("Error closing session: ", e);
62+
}
63+
}
64+
65+
@Override
66+
public void onError(Session session, Throwable throwable) {
67+
client.awaitOpen();
68+
log.error("Error occurred: ", throwable);
69+
if (client.onErrorHandler != null) {
70+
try {
71+
client.onErrorHandler.accept(throwable);
72+
} catch (Exception e) {
73+
log.error("Error executing onError handler: ", e);
74+
}
75+
}
76+
}
77+
}

src/main/resources/log4j.properties

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Set root logger level to DEBUG and its only appender to A1.
2+
log4j.rootLogger=DEBUG, A1
3+
4+
# A1 is set to be a ConsoleAppender.
5+
log4j.appender.A1=org.apache.log4j.ConsoleAppender
6+
7+
# A1 uses PatternLayout.
8+
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
9+
log4j.appender.A1.layout.charset=UTF-8
10+
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
11+
12+
# Print only info for imported libraries.
13+
log4j.logger.io.netty=WARN
14+
log4j.logger.org.eclipse.milo=WARN

0 commit comments

Comments
 (0)