3131import de .gematik .zeta .sdk .WsClientExtension ;
3232import de .gematik .zeta .sdk .ZetaSdk ;
3333import de .gematik .zeta .sdk .ZetaSdkClient ;
34- import de .gematik .zeta .sdk .attestation .model .ClientSelfAssessment ;
34+ import de .gematik .zeta .sdk .attestation .model .AttestationConfig ;
3535import de .gematik .zeta .sdk .attestation .model .PlatformProductId ;
3636import de .gematik .zeta .sdk .authentication .AuthConfig ;
3737import de .gematik .zeta .sdk .authentication .SubjectTokenProvider ;
4646import java .util .HashMap ;
4747import java .util .List ;
4848import java .util .Map ;
49+ import java .util .concurrent .CountDownLatch ;
4950import java .util .concurrent .ExecutorService ;
5051import java .util .concurrent .Executors ;
52+ import java .util .concurrent .TimeUnit ;
53+ import java .util .concurrent .atomic .AtomicReference ;
5154import kotlin .Unit ;
5255import lombok .extern .slf4j .Slf4j ;
5356import org .java_websocket .handshake .ServerHandshake ;
@@ -68,9 +71,11 @@ public class SecureWebSocketClient {
6871 private final boolean disableServerValidation ;
6972 private final URI serverUri ;
7073 private final ZetaSdkClient zetaSdk ;
71- private ExecutorService pool ;
72- private WsClientExtension .WsSession session ;
74+ private final ExecutorService pool ;
75+ private final CountDownLatch sessionReady = new CountDownLatch (1 );
76+ private final AtomicReference <WsClientExtension .WsSession > session = new AtomicReference <>();
7377 private final Map <String , Object > sessionMetadata ;
78+ private final WsClientWrapper wsClientWrapper ;
7479
7580 @ Autowired
7681 public SecureWebSocketClient (
@@ -79,7 +84,8 @@ public SecureWebSocketClient(
7984 @ Value ("${zeta.authentication.smb.keyfile}" ) final String keyfile ,
8085 @ Value ("${zeta.authentication.smb.alias}" ) final String alias ,
8186 @ Value ("${zeta.authentication.smb.password}" ) final String password ,
82- @ Value ("${zeta.client.disableServerValidation}" ) final boolean disableServerValidation ) {
87+ @ Value ("${zeta.client.disableServerValidation}" ) final boolean disableServerValidation ,
88+ final WsClientWrapper wsClientWrapper ) {
8389 this .serverUri = serverUri ;
8490 this .eventPublisher = eventPublisher ;
8591 this .pool = Executors .newFixedThreadPool (1 );
@@ -88,6 +94,7 @@ public SecureWebSocketClient(
8894 this .alias = alias ;
8995 this .password = password ;
9096 this .disableServerValidation = disableServerValidation ;
97+ this .wsClientWrapper = wsClientWrapper ;
9198 this .zetaSdk =
9299 ZetaSdk .INSTANCE .build (
93100 serverUri .toString (),
@@ -98,15 +105,9 @@ public SecureWebSocketClient(
98105 new StorageConfig (
99106 new InMemoryStorage (), "7aae7xXr8rnzVqjpYbosS0CFMrlprkD7jbVotm0fd+w=" ),
100107 new TpmConfig () {},
101- new AuthConfig (List .of ("popp" ), 30 , true , getTokenProvider ()),
102- new ClientSelfAssessment (
103- "name" ,
104- "clientId" ,
105- "manufacturerId" ,
106- "manufacturerName" ,
107- "test@example.com" ,
108- 0 ,
109- new PlatformProductId .AppleProductId ("apple" , "macos" , List .of ("bundleX" ))),
108+ new AuthConfig (
109+ List .of ("popp" ), 30L , true , getTokenProvider (), AttestationConfig .software ()),
110+ new PlatformProductId .AppleProductId ("apple" , "macos" , List .of ("bundleX" )),
110111 new ZetaHttpClientBuilder ("" )
111112 .disableServerValidation (disableServerValidation )
112113 .logging (LogLevel .ALL , message -> log .info ("Ktor HttpClient: {}" , message )),
@@ -118,8 +119,9 @@ private SubjectTokenProvider getTokenProvider() {
118119 if (!Files .isReadable (keyfile )) {
119120 throw new IllegalStateException ("Can't read private key: " + keyfile );
120121 }
122+
121123 return new SmbTokenProvider (
122- new SmbTokenProvider .Credentials (keyfile .toString (), alias , password ));
124+ new SmbTokenProvider .Credentials (keyfile .toString (), alias , password , "" ));
123125 }
124126
125127 @ PostConstruct
@@ -156,59 +158,56 @@ public void onError(final Exception ex) {
156158 }
157159
158160 public boolean isClosed () {
159- return session == null ;
161+ return session . get () == null ;
160162 }
161163
162164 public boolean isOpen () {
163- return session != null ;
165+ return session . get () != null ;
164166 }
165167
166168 public void connectBlocking () {
167- // Start new thread
168-
169169 pool .submit (
170- () -> {
171- WsClientExtension .ws (
172- zetaSdk ,
173- this .serverUri .toString (),
174- builder -> {
175- builder .disableServerValidation (true );
176- return Unit .INSTANCE ;
177- },
178- new HashMap <>(),
179- session -> {
180- this .session = session ;
181- log .info ("Zeta SDK WS connected" );
182-
183- while (true ) {
184- WsClientExtension .WsMessage incoming = session .receiveNext ();
185- if (incoming == null || incoming instanceof WsClientExtension .WsMessage .Close ) {
186- log .debug ("WebSocket closed." );
187- break ;
170+ () ->
171+ wsClientWrapper .ws (
172+ zetaSdk ,
173+ this .serverUri .toString (),
174+ builder -> {
175+ builder .disableServerValidation (true );
176+ return Unit .INSTANCE ;
177+ },
178+ new HashMap <>(),
179+ session -> {
180+ this .session .set (session );
181+ log .info ("Zeta SDK WS connected" );
182+ sessionReady .countDown ();
183+
184+ while (true ) {
185+ WsClientExtension .WsMessage incoming = session .receiveNext ();
186+ if (incoming == null || incoming instanceof WsClientExtension .WsMessage .Close ) {
187+ log .debug ("WebSocket closed." );
188+ break ;
189+ }
190+ if (incoming instanceof WsClientExtension .WsMessage .Text text ) {
191+ log .debug ("WebSocket received: {}" , text .getText ());
192+ onMessage (text .getText ());
193+ } else if (incoming instanceof WsClientExtension .WsMessage .Binary bin ) {
194+ log .debug ("WebSocket received binary (bytes): {}" , bin .getBytes ().length );
195+ }
188196 }
189- if (incoming instanceof WsClientExtension .WsMessage .Text text ) {
190- log .debug ("WebSocket received: " + text .getText ());
191- onMessage (text .getText ());
192- } else if (incoming instanceof WsClientExtension .WsMessage .Binary bin ) {
193- log .debug ("WebSocket received binary (bytes): " + bin .getBytes ().length );
194- }
195- }
196- });
197- });
198-
199- // TODO: instead of busy waiting, use semaphor for inter-thread communication or smth similar
200- while (true ) {
201- if (this .session != null ) break ;
202- try {
203- Thread .sleep (1000 );
204- } catch (InterruptedException e ) {
205- throw new RuntimeException (e );
197+ }));
198+
199+ try {
200+ if (!sessionReady .await (10 , TimeUnit .SECONDS )) {
201+ throw new RuntimeException ("Connection timeout" );
206202 }
203+ } catch (InterruptedException e ) {
204+ Thread .currentThread ().interrupt ();
205+ throw new RuntimeException (e );
207206 }
208207 }
209208
210209 public void send (String messageAsString ) {
211- this .session .sendText (messageAsString );
210+ this .session .get (). sendText (messageAsString );
212211 }
213212
214213 public Map <String , Object > getSSLSession () {
0 commit comments