Skip to content

Commit c0a9894

Browse files
committed
Create io.openliberty.checkpoint_fat_wsoc
1 parent 87eea94 commit c0a9894

File tree

20 files changed

+1003
-0
lines changed

20 files changed

+1003
-0
lines changed

Diff for: dev/io.openliberty.checkpoint_fat_wsoc/.classpath

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="fat/src"/>
4+
<classpathentry kind="src" path="test-applications/basic.war/src"/>
5+
<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
6+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
7+
<attributes>
8+
<attribute name="module" value="true"/>
9+
</attributes>
10+
</classpathentry>
11+
<classpathentry kind="output" path="bin"/>
12+
</classpath>

Diff for: dev/io.openliberty.checkpoint_fat_wsoc/.project

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>io.openliberty.checkpoint_fat_wsoc</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>bndtools.core.bndbuilder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>bndtools.core.bndnature</nature>
22+
</natures>
23+
</projectDescription>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
compileErrorAction=build
2+
eclipse.preferences.version=1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#Ant properties
2+
#Automatically generated by the ant prepare.settings.files task
3+
eclipse.preferences.version=1
4+
encoding/<project>=UTF-8

Diff for: dev/io.openliberty.checkpoint_fat_wsoc/.settings/org.eclipse.jdt.core.prefs

+294
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
eclipse.preferences.version=1
2+
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
3+
org.eclipse.jdt.ui.ignorelowercasenames=true
4+
org.eclipse.jdt.ui.importorder=java;javax;org;com;
5+
org.eclipse.jdt.ui.javadoc=true
6+
org.eclipse.jdt.ui.ondemandthreshold=99
7+
org.eclipse.jdt.ui.staticondemandthreshold=99
8+
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/** */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
9+
sp_cleanup.add_default_serial_version_id=true
10+
sp_cleanup.add_generated_serial_version_id=false
11+
sp_cleanup.add_missing_annotations=true
12+
sp_cleanup.add_missing_deprecated_annotations=true
13+
sp_cleanup.add_missing_methods=false
14+
sp_cleanup.add_missing_nls_tags=false
15+
sp_cleanup.add_missing_override_annotations=true
16+
sp_cleanup.add_missing_override_annotations_interface_methods=true
17+
sp_cleanup.add_serial_version_id=false
18+
sp_cleanup.always_use_blocks=true
19+
sp_cleanup.always_use_parentheses_in_expressions=false
20+
sp_cleanup.always_use_this_for_non_static_field_access=false
21+
sp_cleanup.always_use_this_for_non_static_method_access=false
22+
sp_cleanup.convert_to_enhanced_for_loop=false
23+
sp_cleanup.correct_indentation=false
24+
sp_cleanup.format_source_code=true
25+
sp_cleanup.format_source_code_changes_only=false
26+
sp_cleanup.make_local_variable_final=false
27+
sp_cleanup.make_parameters_final=false
28+
sp_cleanup.make_private_fields_final=false
29+
sp_cleanup.make_type_abstract_if_missing_method=false
30+
sp_cleanup.make_variable_declarations_final=true
31+
sp_cleanup.never_use_blocks=false
32+
sp_cleanup.never_use_parentheses_in_expressions=true
33+
sp_cleanup.on_save_use_additional_actions=true
34+
sp_cleanup.organize_imports=true
35+
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
36+
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
37+
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
38+
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
39+
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
40+
sp_cleanup.remove_private_constructors=true
41+
sp_cleanup.remove_trailing_whitespaces=true
42+
sp_cleanup.remove_trailing_whitespaces_all=true
43+
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
44+
sp_cleanup.remove_unnecessary_casts=true
45+
sp_cleanup.remove_unnecessary_nls_tags=true
46+
sp_cleanup.remove_unused_imports=true
47+
sp_cleanup.remove_unused_local_variables=false
48+
sp_cleanup.remove_unused_private_fields=true
49+
sp_cleanup.remove_unused_private_members=false
50+
sp_cleanup.remove_unused_private_methods=true
51+
sp_cleanup.remove_unused_private_types=true
52+
sp_cleanup.sort_members=false
53+
sp_cleanup.sort_members_all=false
54+
sp_cleanup.use_blocks=false
55+
sp_cleanup.use_blocks_only_for_return_and_throw=false
56+
sp_cleanup.use_parentheses_in_expressions=false
57+
sp_cleanup.use_this_for_non_static_field_access=false
58+
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
59+
sp_cleanup.use_this_for_non_static_method_access=false
60+
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

Diff for: dev/io.openliberty.checkpoint_fat_wsoc/bnd.bnd

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#*******************************************************************************
2+
# Copyright (c) 2025 IBM Corporation and others.
3+
# All rights reserved. This program and the accompanying materials
4+
# are made available under the terms of the Eclipse Public License 2.0
5+
# which accompanies this distribution, and is available at
6+
# http://www.eclipse.org/legal/epl-2.0/
7+
#
8+
# SPDX-License-Identifier: EPL-2.0
9+
#*******************************************************************************
10+
-include= ~../cnf/resources/bnd/bundle.props
11+
bVersion=1.0
12+
13+
src: \
14+
fat/src,\
15+
test-applications/basic.war/src
16+
17+
fat.project: true
18+
19+
tested.features: \
20+
checkpoint,\
21+
servlet-5.0,\
22+
servlet-6.0,\
23+
servlet-6.1,\
24+
websocket-2.0,\
25+
websocket-2.1,\
26+
websocket-2.2
27+
28+
29+
-buildpath: \
30+
org.asynchttpclient:async-http-client;version=2.12.3,\
31+
io.openliberty.io.netty;version=latest,\
32+
com.ibm.websphere.appserver.api.wsoc;version=latest,\
33+
com.ibm.websphere.javaee.servlet.4.0;version=latest,\
34+
com.ibm.ws.wsoc.1.1;version=latest,\
35+
com.ibm.websphere.javaee.websocket.1.0;version=latest

Diff for: dev/io.openliberty.checkpoint_fat_wsoc/build.gradle

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 IBM Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*******************************************************************************/
10+
11+
dependencies {
12+
requiredLibs "org.asynchttpclient:async-http-client:2.12.3",
13+
"org.asynchttpclient:async-http-client-netty-utils:2.12.3",
14+
"com.typesafe.netty:netty-reactive-streams:2.0.4",
15+
"org.reactivestreams:reactive-streams:1.0.4",
16+
'junit:junit:4.12',
17+
project(":io.openliberty.io.netty")
18+
}
19+
addRequiredLibraries.dependsOn addJakartaTransformer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
# YML metadata file made use of by the Cognitive Ecosystem.
3+
# Reference Cognitive Metadata is available at: https://github.com/OpenLiberty/open-liberty/tree/integration/dev/build.example_fat/cognitiveMetadata.yml
4+
# description: Uncomment this field and add a description to give some notes about this bucket.
5+
# triageNotes: Uncomment this field if there are some short notes you would like Pipeline Monitors to see when triaging this bucket.
6+
functionalArea: InstantOn
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
2+
/*******************************************************************************
3+
* Copyright (c) 2025 IBM Corporation and others.
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package io.openliberty.checkpoint.fat;
12+
13+
import static org.junit.Assert.assertNotNull;
14+
import static org.junit.Assert.assertTrue;
15+
16+
import java.lang.StringBuilder;
17+
import java.util.Arrays;
18+
import java.util.concurrent.CountDownLatch;
19+
import java.util.concurrent.TimeUnit;
20+
import java.util.logging.Logger;
21+
22+
import org.asynchttpclient.Dsl;
23+
import org.asynchttpclient.ws.WebSocket;
24+
import org.asynchttpclient.ws.WebSocketListener;
25+
import org.asynchttpclient.ws.WebSocketUpgradeHandler;
26+
import org.junit.AfterClass;
27+
import org.junit.Before;
28+
import org.junit.BeforeClass;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
32+
import com.ibm.websphere.simplicity.ShrinkHelper;
33+
34+
import componenttest.annotation.CheckpointTest;
35+
import componenttest.annotation.Server;
36+
import componenttest.custom.junit.runner.FATRunner;
37+
import componenttest.topology.impl.LibertyServer;
38+
import io.openliberty.checkpoint.spi.CheckpointPhase;
39+
40+
/**
41+
* Verifies SendResult#getSession works per Spec #185
42+
* https://github.com/jakartaee/websocket/issues/185
43+
*/
44+
@RunWith(FATRunner.class)
45+
@CheckpointTest
46+
public class BasicTest {
47+
48+
@Server("basicWsocServer")
49+
public static LibertyServer server;
50+
51+
private static final Logger LOG = Logger.getLogger(BasicTest.class.getName());
52+
53+
private static final String APP_NAME = "basic";
54+
55+
private static Boolean IS_EXPECTED_RESULT = false;
56+
57+
private static CountDownLatch latch;
58+
59+
@BeforeClass
60+
public static void setUp() throws Exception {
61+
62+
// Build the war app and add the dependencies
63+
ShrinkHelper.defaultDropinApp(server, APP_NAME + ".war", "io.openliberty.wsoc.basic");
64+
65+
server.setCheckpoint(CheckpointPhase.AFTER_APP_START, true, null);
66+
server.setCheckpoint(CheckpointPhase.AFTER_APP_START, false,
67+
server -> {
68+
assertNotNull("'SRVE0169I: Loading Web Module: " + APP_NAME + "' message not found in log before rerstore",
69+
server.waitForStringInLogUsingMark("SRVE0169I: .*" + APP_NAME, 0));
70+
assertNotNull("'CWWKZ0001I: Application " + APP_NAME + " started' message not found in log.",
71+
server.waitForStringInLogUsingMark("CWWKZ0001I: .*" + APP_NAME, 0));
72+
});
73+
server.startServer();
74+
server.checkpointRestore();
75+
}
76+
77+
@AfterClass
78+
public static void tearDown() throws Exception {
79+
80+
if (server != null && server.isStarted()) {
81+
server.stopServer();
82+
}
83+
84+
}
85+
86+
@Before
87+
public void resetResult() throws Exception {
88+
IS_EXPECTED_RESULT = false;
89+
latch = null;
90+
}
91+
92+
private WebSocketUpgradeHandler createWebSocketUpgradeHandler(Object expectedResult) {
93+
94+
latch = new CountDownLatch(1); // forces the asserts in each test to be checked once the message is recieved
95+
96+
WebSocketUpgradeHandler.Builder upgradeHandlerBuilder = new WebSocketUpgradeHandler.Builder();
97+
WebSocketUpgradeHandler wsHandler = upgradeHandlerBuilder
98+
.addWebSocketListener(new WebSocketListener() {
99+
@Override
100+
public void onOpen(WebSocket websocket) {
101+
// WebSocket connection opened
102+
LOG.info("Opened Websocket");
103+
}
104+
105+
@Override
106+
public void onClose(WebSocket websocket, int code, String reason) {
107+
// WebSocket connection closed
108+
LOG.info("Closed Websocket");
109+
}
110+
111+
@Override
112+
public void onError(Throwable t) {
113+
// WebSocket connection error
114+
LOG.info("Session Error Occurred: " + t);
115+
}
116+
117+
@Override
118+
public void onBinaryFrame(byte[] payload, boolean finalFragment, int rsv) {
119+
// Log message
120+
StringBuilder sb = new StringBuilder();
121+
for (byte b : payload) {
122+
sb.append((char) b);
123+
}
124+
LOG.info("Debugging binary message: " + sb.toString());
125+
IS_EXPECTED_RESULT = Arrays.equals(payload, (byte[]) expectedResult);
126+
latch.countDown();
127+
}
128+
129+
@Override
130+
public void onTextFrame(String payload, boolean finalFragment, int rsv) {
131+
// Log message
132+
LOG.info("Debugging text message: " + payload);
133+
IS_EXPECTED_RESULT = expectedResult.equals(payload);
134+
latch.countDown();
135+
}
136+
})
137+
.build();
138+
return wsHandler;
139+
}
140+
141+
/*
142+
* Tests that the session after the message is sent is not null
143+
* by comparing IDs before and after the message
144+
*/
145+
@Test
146+
public void testAnnotatedByteArray() throws Exception {
147+
Object expectedResult = "test message".getBytes();
148+
149+
WebSocketUpgradeHandler wsHandler = createWebSocketUpgradeHandler(expectedResult);
150+
151+
WebSocket webSocketClient = Dsl.asyncHttpClient()
152+
.prepareGet("ws://" +
153+
server.getHostname() + ":" +
154+
server.getHttpDefaultPort() + "/" +
155+
APP_NAME +
156+
"/annotatedByteArray/true")
157+
.setRequestTimeout(5000)
158+
.execute(wsHandler)
159+
.get();
160+
161+
if (webSocketClient.isOpen()) {
162+
LOG.info("sending message");
163+
webSocketClient.sendBinaryFrame("test message".getBytes());
164+
}
165+
latch.await(3L, TimeUnit.SECONDS);
166+
webSocketClient.sendCloseFrame();
167+
assertTrue("Results do not match! ", IS_EXPECTED_RESULT);
168+
}
169+
170+
@Test
171+
public void testDecoder() throws Exception {
172+
Object expectedResult = "[class io.openliberty.wsoc.basic.BinaryStreamDecoder]";
173+
174+
WebSocketUpgradeHandler wsHandler = createWebSocketUpgradeHandler(expectedResult);
175+
WebSocket webSocketClient = Dsl.asyncHttpClient()
176+
.prepareGet("ws://" +
177+
server.getHostname() + ":" +
178+
server.getHttpDefaultPort() + "/" +
179+
APP_NAME +
180+
"/defaults")
181+
.setRequestTimeout(5000)
182+
.execute(wsHandler)
183+
.get();
184+
185+
if (webSocketClient.isOpen()) {
186+
LOG.info("sending message");
187+
webSocketClient.sendTextFrame("decoders");
188+
}
189+
latch.await(3L, TimeUnit.SECONDS);
190+
webSocketClient.sendCloseFrame();
191+
assertTrue("Results do not match! ", IS_EXPECTED_RESULT);
192+
}
193+
194+
@Test
195+
public void testUpgrade() throws Exception {
196+
Object expectedResult = "got your message hello world";
197+
198+
WebSocketUpgradeHandler wsHandler = createWebSocketUpgradeHandler(expectedResult);
199+
WebSocket webSocketClient = Dsl.asyncHttpClient()
200+
.prepareGet("ws://" +
201+
server.getHostname() + ":" +
202+
server.getHttpDefaultPort() + "/" +
203+
APP_NAME +
204+
"/upgradeEcho")
205+
.setRequestTimeout(5000)
206+
.execute(wsHandler)
207+
.get();
208+
209+
if (webSocketClient.isOpen()) {
210+
LOG.info("sending message");
211+
webSocketClient.sendTextFrame("hello world");
212+
}
213+
latch.await(3L, TimeUnit.SECONDS);
214+
webSocketClient.sendCloseFrame();
215+
assertTrue("Results do not match! ", IS_EXPECTED_RESULT);
216+
}
217+
218+
}

0 commit comments

Comments
 (0)