目的
LibertyとtWASのJAX-RS環境を構築して HelloWorld のような簡単なプログラムでテストします。
Libertyテスト環境の構築
用意したGitレポジトリをクローンします。
git clone http://github.com/pdprof/jaxrs.git
cd jaxrs/jaxrs-docker
Libertyのイメージをビルドして開始します。
./setup-docker.sh
./start.sh
Libertyの起動を確認します。jaxrs.clientにアクセスします。
tWASテスト環境の構築
Libetyを起動している場合には停止します。
docker stop jaxrs
tWASのイメージをビルドして開始します。
./setup-was90.sh
./was90-start.sh
Liberty, tWAS どちらかを起動しテストします。
構成済みのユーザー
tWASの管理ユーザーは
User | Password |
---|---|
wsadmin | passw0rd |
になっています。Liberty はセキュリティが無効になっています。構成は以下のファイルでされています。
テストコード
実行しているHelloWorldの説明をしつつ、テストします。
JAX-RS Provider
JAX-RS Provider 側は
package pdprof.jaxrs;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("pdprof")
public class PdprofApplication extends Application {
}
package pdprof.jaxrs;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("sleep")
public class SleepService {
@GET
public String hello() {
return "Hello World!!";
}
@POST
@Produces(MediaType.TEXT_PLAIN)
public String sleep(@FormParam("time") String t) {
int i = 10000;
try { i = Integer.parseInt(t); } catch (Exception e) {}
try {
Thread.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Sleep " + t + " milliseconds";
}
}
の2つを WARにパッケージすることで動作します。
@ApplicationPath("pdprof")
@Path("sleep")
@GET
でブラウザで
にアクセスすることで
になります。
JAX-RS Client
クライアントの用意はいくつかあります。確認は以下のフォルダの javaファイルを見ます。
ここでは ReceiveClientServlet をもとに説明します。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("*** ReceiveClientServlet START ***");
String timeout = request.getParameter("timeout");
String sleep = request.getParameter("sleep");
String port = request.getParameter("port");
try { Integer.parseInt(timeout); } catch (Exception e) { timeout = "10000";}
try { Integer.parseInt(sleep); } catch (Exception e) { sleep = "20000";}
try { Integer.parseInt(port); } catch (Exception e) { port = "9080";}
String host = request.getParameter("host");
if (host == null) { host = "localhost"; }
ClientBuilder cb = ClientBuilder.newBuilder().register(new PdprofResponseFilter()).property("com.ibm.ws.jaxrs.client.receive.timeout", timeout);
Client c = cb.build();
String res = null;
Entity<Form> entity = Entity.entity(new Form().param("time", sleep).param("method", "post"),
MediaType.APPLICATION_FORM_URLENCODED_TYPE);
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle("Expect", "100-continue");
try {
res = c.target("http://"+ host + ":" + port + "/jaxrs/pdprof/sleep").request().headers(headers).post(entity, String.class);
} catch (Exception e) {
res = "[Error]:" + e.toString();
System.out.println("*** ReceiveClientServlet ***");
e.printStackTrace();
} finally {
c.close();
}
response.getWriter().append(res);
ほかのクライアントもあわせて、JAX-RSの処理として覚えておくと良いのは
ClientBuilder cb = ClientBuilder.newBuilder().register(new PdprofResponseFilter()).property("com.ibm.ws.jaxrs.client.connection.timeout", timeout);
ClientBuilder cb = ClientBuilder.newBuilder().register(new
PdprofResponseFilter()).property("com.ibm.ws.jaxrs.client.receive.timeout", timeout);
Entity<Form> entity = Entity.entity(new Form().param("time", sleep).param("method", "post"),
MediaType.APPLICATION_FORM_URLENCODED_TYPE);
res = c.target("http://"+ host + ":" + port + "/jaxrs/pdprof/sleep").request().headers(headers).post(entity, String.class);
- Connect Timeout : com.ibm.ws.jaxrs.client.connection.timeout
- Response Timeout : com.ibm.ws.jaxrs.client.receive.timeout
- ClientResponseFilter : PdprofResponseFilter()
- POSTするデータの登録とリクエスト送信
やりたいことに合わせて、コードを変更します。
JAX-RS クライアントのテスト
コードの説明をしたのでテストします。LibertyやtWASが起動できていれば、http://localhost:9080/jaxrs.client/ にアクセスできます。
Connect timeout
相手先がみつからず、TCPIPの接続完了がタイムアウトするテストです。10.10.10.10 などネットワークにいないIPを指定して submit です。
[Error]:javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: SocketTimeoutException invoking http://10.10.10.10:9080/jaxrs/pdprof/sleep: connect timed out
Libertyテスト時のログです。
*** ConnectClientServlet ***
[err] javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: SocketTimeoutException invoking http://10.10.10.10:9080/jaxrs/pdprof/sleep: connect timed out
[err] at org.apache.cxf.jaxrs.client.AbstractClient.checkClientException(AbstractClient.java:632)
[err] at [internal classes]
[err] at pdprof.jaxrs.client.ConnectClientServlet.doGet(ConnectClientServlet.java:57)
[err] at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
[err] at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
[err] at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1260)
[err] at [internal classes]
[err] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[err] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[err] at java.base/java.lang.Thread.run(Thread.java:839)
[err] Caused by:
[err] java.net.SocketTimeoutException: SocketTimeoutException invoking http://10.10.10.10:9080/jaxrs/pdprof/sleep: connect timed out
[err] at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[err] at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[err] at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[err] at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
[err] at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1458)
[err] at [internal classes]
[err] ... 34 more
[err] Caused by:
[err] java.net.SocketTimeoutException: connect timed out
[err] at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
[err] at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
[err] at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
[err] at java.base/java.net.Socket.connect(Socket.java:609)
[err] at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177)
[err] at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:507)
[err] at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:602)
[err] at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:275)
[err] at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:374)
[err] at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:395)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1253)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1232)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1081)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1015)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1367)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1342)
[err] at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:334)
[err] at [internal classes]
[err] ... 41 more
*** ConnectClientServlet END ***
Receive timeout
相手先にリクエストは送信できたが、応答が戻らずにタイムアウトするテストです。Sleep time を Receive timeout より長くして submit です。hostname の調整で、tWAS環境にアクセスさせることもできます。
[Error]:javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: SocketTimeoutException invoking http://localhost:9080/jaxrs/pdprof/sleep: Read timed out
Libertyテスト時のログです。
*** ReceiveClientServlet START ***
*** ReceiveClientServlet ***
[err] javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: SocketTimeoutException invoking http://localhost:9080/jaxrs/pdprof/sleep: Read timed outJAX-RS
[err] at org.apache.cxf.jaxrs.client.AbstractClient.checkClientException(AbstractClient.java:632)
[err] at [internal classes]
[err] at pdprof.jaxrs.client.ReceiveClientServlet.doGet(ReceiveClientServlet.java:55)
[err] at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
[err] at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
[err] at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1260)
[err] at [internal classes]
[err] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[err] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[err] at java.base/java.lang.Thread.run(Thread.java:839)
[err] Caused by:
[err] java.net.SocketTimeoutException: SocketTimeoutException invoking http://localhost:9080/jaxrs/pdprof/sleep: Read timed out
[err] at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[err] at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[err] at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[err] at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
[err] at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1458)
[err] at [internal classes]
[err] ... 33 more
[err] Caused by:
[err] java.net.SocketTimeoutException: Read timed out
[err] at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
[err] at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168)
[err] at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
[err] at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
[err] at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292)
[err] at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
[err] at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:787)
[err] at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:925)
[err] at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:722)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1615)
[err] at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
[err] at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
[err] at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream$2.run(URLConnectionHTTPConduit.java:441)
[err] at [internal classes]
[err] at java.base/java.security.AccessController.doPrivileged(AccessController.java:746)
[err] at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.getResponseCode(URLConnectionHTTPConduit.java:437)
[err] at [internal classes]
[err] ... 40 more
*** ReceiveClientServlet END ***
Simple JAX-RS client
最後にエラーなしのクライアントです。http://localhost:9080/jaxrs.client/get をクリックすると以下のページが出力されます。クライアントからの送信されたリクエストヘッダーが確認できます。
トラブルシューティング
毎度のことですが、よくつかう dockerコマンドを書いておきます。この文書でもpodman, dockerとまとまりがないですが、Linux では dockerがpodmanを呼び出すようになっていました。
docker ps # 動作中のContainer確認
docker logs -f jaxrs # ログ確認
docker restart jaxrs # 再起動
docker inspect jaxrs # container 確認
docker exec -it jaxrs bash # Container内状況確認
まとめ
LibertyとtWASの環境を構築して、JAX-RSをテストしました。