CICS-Javaアプリケーションを動かす - (4)Spring Bootアプリ

# はじめに
CICS TS for z/OSでは、Libertyの稼働がサポートされているので、CICS上でJavaEEアプリケーションを動かすことができます。
CICS TS V5.3からSpring Bootをサポートするようになったため、Spring BootのアプリケーションもCICS上で(CICS上のLibertyで)稼働できるようになりました。CICS上で動くということは、CICSの機能を使用するJCICSが使えるということなので、既存のCICSプログラムを呼び出すWebアプリ、CICS管理のVSAMやTSQをアクセスするWebアプリ、といったものがCICSだけで動く、さらにそれをSpring Bootフレームワークを使って開発できる、ということになります。

この記事では、以下GitHubに提供されているCICS-SpringBootアプリのサンプルを動かしてみます。
[cics-java-liberty-springboot-jcics](https://github.com/cicsdev/cics-java-liberty-springboot-jcics)

ビルドの管理にはMaven or Gradleどちらも利用できるようになってますが、ここではGradleを使ってみます。


## 関連記事
[CICS-Javaアプリケーションを動かす - (1)単純なサンプルアプリの稼働](https://qiita.com/tomotagwork/items/aac10ad84fe83d88bb5f)
[CICS-Javaアプリケーションを動かす - (2)Mavenによるビルド管理](https://qiita.com/tomotagwork/items/a487484835d4e8dd2d6f)
[CICS-Javaアプリケーションを動かす - (3)Gradleによるビルド管理](https://qiita.com/tomotagwork/items/6fae5bd3440635ad26af)
[CICS-Javaアプリケーションを動かす - (4)Spring Bootアプリ](https://qiita.com/tomotagwork/items/9bdef46069e1591103ba)
[CICS-Javaアプリケーションを動かす - (5)JCICSXの利用](https://qiita.com/tomotagwork/items/cac290f6435453c19b7b)

# 環境情報
**開発環境**
Windows10
CICS Explorer V5.6

**実行環境**
z/OS V2.4
CICS Transaction Server for z/OS V5.6

# 事前準備

※Gradleでデプロイへの管理まで行う場合、デプロイ先のCICSはCICSplex管理下にある必要があります。

## 開発環境(PC)

### 適当なJavaEE開発環境

EclipseやVS CodeなどJavaEEアプリケーション開発ができるものを適宜使用してください。
今回はサンプルをそのまま使うので特にソースの編集はしないので使わなくてもよいですが、通常はなんらかの開発環境使うことになるでしょう。Gradle, gitなどと連携できるとよいかも。
CICS Explorerを一緒に使うのであればEclipse使っておけばOK。

### CICS Explorer

こちらも必須ではありませんが、CICSの資源定義とか確認するのに使えます。
以下の辺りを参考にCICS ExplorerというEclipseベースのツールをダウンロードしてセットアップしておきます。
参考: [Downloading and starting CICS Explorer](https://www.ibm.com/support/knowledgecenter/SSSQ3W_5.5.0/com.ibm.cics.core.help/topics/concepts/install_planning_client.html)
※このツールはCICS利用者は無償で使えるツールです。

### Gradle
以下の手順に従ってインストールします。
[Installing Gradle](https://docs.gradle.org/6.5/userguide/installation.html)
基本的には、ダウンロードしたものを解凍してパスを通すだけ。

前提としてJava8以降が必要になります。

```
c:\>java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
```

以下から現時点での最新版Gradle V6.5をダウンロードします(gradle-6.5.zip)。
[Releases](https://gradle.org/releases/)

適当なディレクトリに展開します。(ここでは(c:\x\Gradle\gradle-6.5\)
展開先のbin(C:\x\Gradle\gradle-6.5\bin)をPATHに追加します。

確認

```
c:\>gradle -v

------------------------------------------------------------
Gradle 6.5
------------------------------------------------------------

Build time:   2020-06-02 20:46:21 UTC
Revision:     a27f41e4ae5e8a41ab9b19f8dd6d86d7b384dad4

Kotlin:       1.3.72
Groovy:       2.5.11
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_144 (Oracle Corporation 25.144-b01)
OS:           Windows 10 10.0 amd64
```

これでOKです。

### git

gitHubに提供されるサンプルを入手して使用するので、gitもインストールしておきます。
セットアップ方法などはその辺に転がってるので割愛。

```
c:\>git --version
git version 2.21.0.windows.1
```

## 実行環境(z/OS, CICS)

サンプルを稼働させるCICSリージョンを用意します。
ここでは、CICSplex管理下の**CT56B4A1**という名前のリージョンを使うことにします。
そこに、Javaアプリケーションを稼働させるためのJVMServerという資源を追加します。
今回は、CICS-Liberty用のサンプル(JavaEEアプリケーション)を使用するので、Liberty用のJVMServerを作成しておきます。

### JVMプロファイル

USS上にJVMプロファイルを準備します。(JVMServerに関するプロパティーは実質このUSS上のファイルに指定します。JVMSERVER資源定義ではこのJVMプロファイルのファイル名をポイントすることになります。)
サンプルが提供されているのでそれをコピーして使用します。

/var/cicsts/cicsts56/CT56B4A1/JVMProfiles というディレクトリを作成し、そこに/usr/lpp/cicsts/cicsts56/JVMProfiles/DFHWLP.jvmprofile(CICS導入ディレクトリ下に配置されているLiberty用のサンプル定義)をコピーします。
環境に合わせて適宜カスタマイズします。

```xxx:DFHWLP.jvmprofile抜粋
JAVA_HOME=/usr/lpp/java/J8.0_64/
WORK_DIR=/var/cicsts/cicsts56/CT56B4A1/work
WLP_INSTALL_DIR=/usr/lpp/cicsts/cicsts56/wlp
-Dcom.ibm.cics.jvmserver.wlp.autoconfigure=true
-Dcom.ibm.cics.jvmserver.wlp.server.host=*
-Dcom.ibm.cics.jvmserver.wlp.server.http.port=56441
-Dcom.ibm.cics.jvmserver.wlp.server.https.port=56451
-Xms128M
-Xmx256M
-Xmso1M
-Xgcpolicy:gencon
-Xscmx256M
-Xshareclasses:name=cicsts%g,groupAccess,nonfatal
-Xtune:virtualized
-Dcom.ibm.tools.attach.enable=no
-Dfile.encoding=ISO-8859-1
_BPXK_DISABLE_SHLIB=YES
```

### SIT

上のプロパティーファイルを配置したディレクトリを、SITパラメーター"JVMPROFILEDIR"に指定します。

```
JVMPROFILEDIR=/var/cicsts/cicsts56/CT56B4A1/JVMProfiles 
```

変更反映のためにリージョンを再起動します。

### JVMServer定義

JVMSERVER資源定義を準備します。
製品提供のDFH$WLPというグループにあるJVMSERVER定義"DFHWLP"を適当なグループにコピーしてインストールします。

```
OBJECT CHARACTERISTICS                                    CICS RELEASE = 0730
 CEDA  View JVmserver( DFHWLP   )                                            
  JVmserver      : DFHWLP                                                    
  Group          : TAGGRP                                                    
  DEScription    : CICS JVM server to run WLP samples                        
  Status         : Enabled            Enabled | Disabled                     
  Jvmprofile     : DFHWLP                                         (Mixed Case
  Lerunopts      : DFHAXRO                                                   
  Threadlimit    : 015                1-256                                  
 DEFINITION SIGNATURE                                                        
  DEFinetime     : 06/04/20 16:20:21                                         
  CHANGETime     : 06/04/20 16:20:21                                         
  CHANGEUsrid    : CICSUSER                                                  
  CHANGEAGEnt    : CSDApi             CSDApi | CSDBatch                      
  CHANGEAGRel    : 0730                                                                     
```

※Jvmprofile: DFHWLPとなっていますが、これはSITのJVMPROFILEDIRに指定されたディレクトリ下のDFHWLP.jvmprofileというファイルがJVMプロパティーファイルとして使用されることを意味します。


CEMT I JVMSERVERで見てEnableになっていればOK。

```
I JVMS                                             
STATUS:  RESULTS - OVERTYPE TO MODIFY              
 Jvm(DFHWLP  ) Ena     Prf(DFHWLP  ) Ler(DFHAXRO ) 
    Threadc(005) Threadl( 015 ) Cur(48314096)           
```

### server.xml変更

今回のサンプル実行手順では、Deployまでを自動でやるのではなく手動でデプロイするような手順になっているので、そのための設定を追加しておきます。

JVMプロファイルで`-Dcom.ibm.cics.jvmserver.wlp.autoconfigure=true`を指定すると、Libertyの構成が自動で行われます。一度JVMSERVER定義をインストールすると、workディレクトリ下にLibertyが構成されます(`work/CT56B4A1/DFHWLP/wlp/usr/servers/defaultServer`)。
このディレクトリ下のserver.xmlを修正して以下のようにします。

```xml:server.xml
...
<applicationMonitor dropins="dropins" dropinsEnabled="true" pollingRate="5s" updateTrigger="polled"/>
...
```

このように、dropinsEnabled="true", updateTrigger="polled"を指定します。
これで、dropinsディレクトリに配置されたwarを自動で検知してくれます。
同ディレクトリにdropinsディレクトリを作成しておきます(`.../work/CT56B4A1/DFHWLP/wlp/usr/servers/defaultServer/dropins`)。

変更したらJVMServerを再起動しておきます。

 
### CICS Bundle Deployment API
CICS TS V5.6から提供されるようになったCICS Bundle Deployment APIのセットアップをしておく必要があります。(サンプル手順の手動デプロイの場合は不要)
この機能は、CMCIと呼ばれるRESTベースの管理APIの一つとしてアプリケーションのデプロイ用に追加されました。
ターゲットのCICSリージョンを管理するWUIサーバー上にCMCIをセットアップし、CMCI JVMサーバーのプロパティーで、CICS Bundle Deployment API用のパラメーターを指定します。
参考: [How it works: CICS bundle deployment API](https://www.ibm.com/support/knowledgecenter/SSGMCP_5.6.0/fundamentals/cpsm/cics-bundle-api.html)

最低限必要な設定は以下の通りです。
USS上にBundleファイル配置用のディレクトリを作成します。ここでは`/var/cicsts/cicsts56/bundles`とします。
WUIのCMCI JVM Server用のJVMプロファイル(EYUCMCIJ.jvmprofile)に、以下のパラメーターを設定します。
`-Dcom.ibm.cics.jvmserver.cmci.bundles.dir=/var/cicsts/cicsts56/bundles`

# サンプルの稼働確認(1) / 手動デプロイ
まずはgithubに提供されている手順に従って動かしてみます。
参考: [cics-java-liberty-springboot-jcics](https://github.com/cicsdev/cics-java-liberty-springboot-jcics)

## ローカルにクローン作製
適当なディレクトリを作成しローカルのPCに`https://github.com/cicsdev/cics-java-liberty-springboot-jcics.git`のクローンを作成します。

```
c:\y\workspace\cicsts56>git clone https://github.com/cicsdev/cics-java-liberty-springboot-jcics.git
Cloning into 'cics-java-liberty-springboot-jcics'...
remote: Enumerating objects: 67, done.
remote: Counting objects: 100% (67/67), done.
remote: Compressing objects: 100% (43/43), done.
remote: Total 67 (delta 12), reused 56 (delta 7), pack-reused 0
Unpacking objects: 100% (67/67), done.
```

## ファイル構造の理解
ディレクトリ"cics-java-liberty-springboot-jcics"に移動して、ファイルの構造を見てみます。

```
c:\y\workspace\cicsts56\cics-java-liberty-springboot-jcics>tree /f /a
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 1866-E2FC です
C:.
|   .classpath
|   .gitignore
|   .project
|   build.gradle
|   gradlew
|   gradlew.bat
|   LICENSE
|   mvnw
|   mvnw.cmd
|   pom.xml
|   README.md
|   settings.gradle
|
+---.mvn
|   \---wrapper
|           maven-wrapper.jar
|           maven-wrapper.properties
|           MavenWrapperDownloader.java
|
+---.settings
|       org.eclipse.buildship.core.prefs
|       org.eclipse.wst.common.component
|       org.eclipse.wst.common.project.facet.core.xml
|
+---gradle
|   \---wrapper
|           gradle-wrapper.jar
|           gradle-wrapper.properties
|
\---src
    \---main
        +---java
        |   \---com
        |       \---ibm
        |           \---cicsdev
        |               \---springboot
        |                   \---jcics
        |                           Application.java
        |                           BrowseTSQController.java
        |                           DeleteTSQController.java
        |                           ServletInitializer.java
        |                           TSQInfoController.java
        |                           WriteTSQController.java
        |
        \---webapp
            \---WEB-INF
                    ibm-web-ext.xml
                    web.xml
```

アプリ部分の単発プロジェクトです。
CICS Bundleプロジェクトは含まれていません。
Maven, Gradle両方に対応しているようですが、ここではGradleを使います。


## 中身の確認/編集

いくつかソースがありますが、例えばWriteTSQController.javaを見てみます。これは見るだけ。

```java:WriteTSQController.java
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* SAMPLE                                                                 */
/*                                                                        */
/* (c) Copyright IBM Corp. 2020 All Rights Reserved                       */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or disclosure */
/* restricted by GSA ADP Schedule Contract with IBM Corp                  */
/*                                                                        */

package com.ibm.cicsdev.springboot.jcics;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ibm.cics.server.CicsConditionException;
import com.ibm.cics.server.TSQ;

@RestController
public class WriteTSQController {

	/**
	 * The @GetMapping annotation ensures that HTTP GET requests are mapped to the annotated method. 
	 * @throws IOException 
	 **/
	@GetMapping("/writeTSQs")
	public String writeTSQs(@RequestParam(value = "tsqName", defaultValue = "ANNE") String tsqName,
			@RequestParam(value = "tsqContent", defaultValue = "Spring greetings from CICS!") String tsqContent) {

		String response = "";

		// Write to the TSQ
		try {
			response = writeTSQ(tsqName, tsqContent);
		} catch ( CicsConditionException | UnsupportedEncodingException e) {

			// Print the stack trace
			e.printStackTrace();

			// Return useful information to the user when meeting errors
			return "Oops! Unexpected CICS condition exception: "  + e.getMessage() + ". Please check stderr for details.";
		}
		return response;
	}

	/**
	 * A method to write a record to a TSQ
	 * 
	 * @param tsqName, the name of the TSQ to be written to
	 * @param record, the data to be written to the TSQ
	 * @return, the result of the write 
	 * @throws UnsupportedEncodingException 
	 * @throws CicsConditionException	   
	 */
	private String writeTSQ(String tsqName, String record) throws CicsConditionException, UnsupportedEncodingException{
		
		// Construct the TSQ object
		TSQ tsqQ = new TSQ();
		tsqQ.setName(tsqName);

		// the result of writing an item to the TSQ
		String result = "";

		// write the record to the TSQ
		tsqQ.writeString(record);		
		result = "Record written to TSQ " + tsqName + ".";

		// return the result to the calling servlet
		return result;
	}
}
```

JCICSのTSQクラスを使ってTSQにデータを書き込むだけの単純なアプリです。URI `/writeTSQs`のquery parameterでtsqName, tsqContentを受け取り、tsqNameで指定されたTSQにtsqContentで指定された値を書き込むようになっています。

ibm-web-ext.xmlで、context-rootを確認しておきます。これも確認のみ。

```xml:ibm-web-ext.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-ext
	xmlns="http://websphere.ibm.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
	version="1.0">

	<reload-interval value="3"/>
	<context-root uri="cics-java-liberty-springboot-jcics-ding" />
	<enable-directory-browsing value="false"/>
	<enable-file-serving value="true"/>
	<enable-reloading value="true"/>
	<enable-serving-servlets-by-class-name value="false" />

</web-ext>
```

build.gradleを開いて、依存関係の指定をターゲットのCICSのバージョンに合わせて編集します。ここではCICS TS V5.6をターゲットとするので、以下のように修正します。

```gradle:build.gradle
...
compileOnly enforcedPlatform("com.ibm.cics:com.ibm.cics.ts.bom:5.6-20200609123739")
...
```

指定する値は以下から判断することになります。
参考:[IBM CICS TS BOM](https://mvnrepository.com/artifact/com.ibm.cics/com.ibm.cics.ts.bom)


## ビルド

以下のコマンドでビルドします。

```
c:\y\workspace\cicsts56\cics-java-liberty-springboot-jcics>gradlew.bat clean bootwar
Downloading https://services.gradle.org/distributions/gradle-6.5-bin.zip
.........10%..........20%..........30%..........40%.........50%..........60%..........70%..........80%.........90%..........100%
Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 1m 35s
3 actionable tasks: 2 executed, 1 up-to-date
```

成功すると、以下のWARが作成されます。
`build/libs/cics-java-liberty-springboot-jcics-0.1.0.war`

## デプロイ
このサンプルの手順では手動でWARをデプロイするようになっているので、一旦それでやってみます。

先に作成しておいた、dropinsディレクトリにバイナリモードで上のWARファイルを転送します。
これで自動でアプリが認識されるはずです。
(この方式の場合、BUNDLE定義は使いません)

## アプリ稼働確認

ブラウザから、ターゲットのLibertyがListenしているhost:portに対して以下のようなリクエストを投げてみます。
`http://etp1:56441/cics-java-liberty-springboot-jcics-ding/writeTSQs?tsqName=SPGJCICS&tsqContent=ILOVECICS`
SPGJCICSという名前のTSQにILOVECICSというメッセージを投入することになります。
うまくいけば、TSQにデータが書き込まれるので、CICS端末からCEBRで確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/2a036830-9eeb-a2c4-6320-4d6a9776c959.png)
きちんとデータが投入されていることが確認できました。

# サンプルの稼働確認(2) / Gradleによるデプロイ
さて、上の手順だとデプロイが手動になってしまいスマートでは無いので、DeployまでGradleで実施できるようCICS Bundleプロジェクトを追加してみます。

<font color="red"> 注意！: 上の手順で手動デプロイを試した場合は、アプリがバッティングするのでdropinsディレクトリのwarを削除し、JVMSERVERを再起動しておいてください。</font>

## Gradleマルチプロジェクト作成
CICS Bundleプロジェクトを追加し、サンプルで提供されているWARとまとめるための親のプロジェクトを作成します。

### 親プロジェクト
まず、親となるプロジェクトのディレクトリ `cics-springboot01`というディレクトリを作成します。そこでgradle wrapperを実行しておきます。

```
c:\y\workspace\cicsts56\cics-springboot01>gradle wrapper

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 6s
1 actionable task: 1 executed
```

```
c:\y\workspace\cicsts56\cics-springboot01>tree /a /f
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 1866-E2FC です
C:.
|   gradlew
|   gradlew.bat
|
+---.gradle
|   +---6.5
|   |   |   gc.properties
|   |   |
|   |   +---executionHistory
|   |   |       executionHistory.bin
|   |   |       executionHistory.lock
|   |   |
|   |   +---fileChanges
|   |   |       last-build.bin
|   |   |
|   |   +---fileHashes
|   |   |       fileHashes.bin
|   |   |       fileHashes.lock
|   |   |
|   |   \---vcsMetadata-1
|   +---buildOutputCleanup
|   |       buildOutputCleanup.lock
|   |       cache.properties
|   |       outputFiles.bin
|   |
|   +---checksums
|   |       checksums.lock
|   |
|   \---vcs-1
|           gc.properties
|
\---gradle
    \---wrapper
            gradle-wrapper.jar
            gradle-wrapper.properties
```

ここに、以下のようにbuild.gradle, setting.gradleを作成します。

```gradle:build.gradle
group 'com.ibm.cicsdev.springboot'
version '1.0.0'
```

```gradle:setting.gradle
rootProject.name = 'cics-springboot01'
include 'cics-java-liberty-springboot-jcics'
include 'cics-springboot-bundle04'
```

### 子プロジェクト(1) / WAR用

これは、サンプルで提供されているものをそのまま使います。
上で示した手順通り、親プロジェクトのディレクトリ下でgit cloneでcics-java-liberty-springboot-jcicsをクローンします。
その後、ターゲットのCICSのバージョンに合わせて、build.gradleのcompileOnlyの行を修正します。

### 子プロジェクト(2) / CICS Bundle用

これは前回の記事を参考に、バンドル用のbuild.gradleを作成してきます。
参考: [CICS-Javaアプリケーションを動かす - (3)Gradleによるビルド管理](https://qiita.com/tomotagwork/items/6fae5bd3440635ad26af)

親プロジェクトのディレクトリ下に、`cics-springboot-bundle04`という名前のディレクトリを作成し、そこに以下のようなbuild.gradleを作成します。ディレクトリ名は親のsetting.gradleで指定した名前に合わせます。

```gradle:build.gradle
plugins {
    id 'com.ibm.cics.bundle' version '1.0.0'
}

group 'com.ibm.cicsdev.springboot'
version '1.0.0'

repositories {
    mavenCentral()
}

cicsBundle {
    build {
        defaultJVMServer = 'DFHWLP' // (1)JVMSERVER名
    }
    deploy {
        cicsplex = 'C73PLX'         // (2) ターゲットのCICSリージョンが属しているCICSplex名
        region   = 'CT56B4A1'       // (3) ターゲットのCICSリージョン名
        bunddef  = 'SPBBUNDL'       // (4) ターゲットのCICSリージョン上に定義したバンドル定義資源名
        csdgroup = 'TAGGRP'         // (5) (4)のバンドル定義が属しているCSDグループ名
        url      = 'http://etp1:56002'     // (6) WUIのCMCIのURL
        username = 'TAG'           // (7) CMCIによるDeployment API発行時に使用するユーザーと
        password = 'xxxxxxxx'      // 　　パスワード
        //caution: uncomment the line below to disable TLS/SSL checking for certificates
        //insecure = true
    }
}

dependencies {
    cicsBundlePart project(path:':cics-java-liberty-springboot-jcics', configuration: 'archives')
}
```

最終的にはこんな感じの構造になります。

```
c:\y\workspace\cicsts56\cics-springboot01>tree /a /f
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 1866-E2FC です
C:.
|   build.gradle
|   gradlew
|   gradlew.bat
|   settings.gradle
|

...

+---cics-java-liberty-springboot-jcics
|   |   .classpath
|   |   .gitignore
|   |   .project
|   |   build.gradle
|   |   build_original.gradle
|   |   gradlew
|   |   gradlew.bat
|   |   LICENSE
|   |   mvnw
|   |   mvnw.cmd
|   |   pom.xml
|   |   README.md
|   |   settings.gradle
|   |
|   +---.gradle
|   |   +---6.5
|   |   |   |   gc.properties
|   |   |   |
|   |   |   +---executionHistory
|   |   |   |       executionHistory.bin
|   |   |   |       executionHistory.lock
|   |   |   |
|   |   |   +---fileChanges
|   |   |   |       last-build.bin
|   |   |   |
|   |   |   +---fileContent
|   |   |   |       fileContent.lock
|   |   |   |
|   |   |   +---fileHashes
|   |   |   |       fileHashes.bin
|   |   |   |       fileHashes.lock
|   |   |   |
|   |   |   +---javaCompile
|   |   |   |       classAnalysis.bin
|   |   |   |       javaCompile.lock
|   |   |   |       taskHistory.bin
|   |   |   |
|   |   |   \---vcsMetadata-1
|   |   +---buildOutputCleanup
|   |   |       buildOutputCleanup.lock
|   |   |       cache.properties
|   |   |       outputFiles.bin
|   |   |
|   |   +---checksums
|   |   |       checksums.lock
|   |   |       md5-checksums.bin
|   |   |       sha1-checksums.bin
|   |   |
|   |   \---vcs-1
|   |           gc.properties
|   |
|   +---.mvn
|   |   \---wrapper
|   |           maven-wrapper.jar
|   |           maven-wrapper.properties
|   |           MavenWrapperDownloader.java
|   |
|   +---.settings
|   |       org.eclipse.buildship.core.prefs
|   |       org.eclipse.wst.common.component
|   |       org.eclipse.wst.common.project.facet.core.xml
|   |
|   +---gradle
|   |   \---wrapper
|   |           gradle-wrapper.jar
|   |           gradle-wrapper.properties
|   |
|   \---src
|       \---main
|           +---java
|           |   \---com
|           |       \---ibm
|           |           \---cicsdev
|           |               \---springboot
|           |                   \---jcics
|           |                           Application.java
|           |                           BrowseTSQController.java
|           |                           DeleteTSQController.java
|           |                           ServletInitializer.java
|           |                           TSQInfoController.java
|           |                           WriteTSQController.java
|           |
|           \---webapp
|               \---WEB-INF
|                       ibm-web-ext.xml
|                       web.xml
|
+---cics-springboot-bundle04
|       build.gradle
|
\---gradle
    \---wrapper
            gradle-wrapper.jar
            gradle-wrapper.properties
```


## BUNDLE定義作成

上のbuild.gradleで指定した内容に従って、バンドル定義を作成します。

```
OBJECT CHARACTERISTICS                                    CICS RELEASE = 0730 
 CEDA  View Bundle( SPBBUNDL )                                                
  Bundle         : SPBBUNDL                                                   
  Group          : TAGGRP                                                     
  DEScription    : CICS-SpringBoot-Sample                                     
  Status         : Enabled            Enabled | Disabled                      
  BUndledir      : /var/cicsts/cicsts56/bundles/cics-springboot-bundle04_1.0. 
  (Mixed Case)   : 0                                                          
                 :                                                            
                 :                                                            
                 :                                                            
  BAsescope      :                                                            
  (Mixed Case)   :                                                            
                 :                                                            
                 :                                                            
                 :                                                            
 DEFINITION SIGNATURE                                                         
  DEFinetime     : 07/07/20 17:03:45                                          
  CHANGETime     : 07/07/20 17:03:57                                          
                                                                              
                                                    SYSID=B4A1 APPLID=CT56B4A1
                              DSN=CICSTS56.CICS.DFHCSD                        
```

CSDグループは(5)、BUNDLE定義名は(4)、BUNDLEDIRはプロジェクトのディレクトリ名およびバージョン情報の値を元に指定します。
※ここでは、まだインストール操作はしません

## ビルド/デプロイ実行

以下のようにSpring BootのWARをビルドします。

```
c:\y\workspace\cicsts56\cics-springboot01>gradlew bootWar

BUILD SUCCESSFUL in 6s
2 actionable tasks: 2 executed
```

続いて、CICS Bundleのビルドとデプロイを実行します。

```
c:\y\workspace\cicsts56\cics-springboot01>gradlew deployCICSBundle

> Task :cics-springboot-bundle04:buildCICSBundle
Adding Java-based bundle parts from 'cicsBundlePart' dependency configuration
Adding Java-based bundle part: 'C:\y\workspace\cicsts56\cics-springboot01\cics-java-liberty-springboot-jcics\build\libs\cics-java-liberty-springboot-jcics-0.1.0.war'
Adding non-Java-based bundle parts from 'src/main/resources'

> Task :cics-springboot-bundle04:deployCICSBundle
Task deployCICSBundle

BUILD SUCCESSFUL in 29s
4 actionable tasks: 3 executed, 1 up-to-date
```

CICS Explorerからバンドル、バンドルパーツがENABLEDになっているのが確認できればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/9321b30e-acfa-0907-aa2e-bb1d5e3473f4.png)

デプロイまでGradleでできました！

ちなみに、Libertyのmessages.logをみると、SpringBootのアプリが稼働したのが分かります。

```
[7/7/20 9:20:35:354 GMT] 000000d0 LogService-87-com.ibm.cics.wlp.bundlepart.impl               I CWWKE0703I: [com.ibm.cics.wlp.bundlepart.impl] [CICSLibertyBundlepartControllerImpl] @Info : installBundlepart() - cics-java
-liberty-springboot-jcics-0.1.0, SPBBUNDL, 2, /var/cicsts/cicsts56/bundles/cics-springboot-bundle04_1.0.0/, 1.0.0, 206F2740000001E9, , , -1, -1, -1, CSD_API
[7/7/20 9:20:35:376 GMT] 000000d1 LogService-87-com.ibm.cics.wlp.bundlepart.impl               I CWWKE0703I: [com.ibm.cics.wlp.bundlepart.impl] [CICSLibertyBundlepartControllerImpl] @Info : enableBundlepart() - 3549516473

[7/7/20 9:20:36:381 GMT] 00000055 com.ibm.ws.app.manager.AppMessageHelper                      I CWWKZ0018I: Starting application cics-java-liberty-springboot-jcics-0.1.0.
[7/7/20 9:20:36:382 GMT] 00000055 bm.ws.app.manager.war.internal.WARDeployedAppInfoFactoryImpl I CWWKZ0136I: The cics-java-liberty-springboot-jcics-0.1.0 application is using the archive file at the /var/cicsts/cicsts56/C
T56B4A1/work/CT56B4A1/DFHWLP/wlp/usr/servers/defaultServer/installedApps/cics-java-liberty-springboot-jcics-0.1.0.war location.
[7/7/20 9:20:36:723 GMT] 00000055 com.ibm.ws.webcontainer.osgi.webapp.WebGroup                 I SRVE0169I: Loading Web Module: cics-java-liberty-springboot-jcics.
[7/7/20 9:20:36:723 GMT] 00000055 com.ibm.ws.webcontainer                                      I SRVE0250I: Web Module cics-java-liberty-springboot-jcics has been bound to default_host.
[7/7/20 9:20:36:723 GMT] 00000055 com.ibm.ws.http.internal.VirtualHostImpl                     A CWWKT0016I: Web application available (default_host): http://etp1:56441/cics-java-liberty-springboot-jcics-ding/
[7/7/20 9:20:36:725 GMT] 00000055 com.ibm.ws.app.manager.AppMessageHelper                      A CWWKZ0003I: The application cics-java-liberty-springboot-jcics-0.1.0 updated in 0.344 seconds.
[7/7/20 9:20:36:733 GMT] 0000004d com.ibm.ws.webcontainer.osgi.mbeans.PluginGenerator          I SRVE9103I: A configuration file for a web server plugin was automatically generated for this server at /var/cicsts/cicsts56/
CT56B4A1/work/CT56B4A1/DFHWLP/wlp/usr/servers/defaultServer/logs/state/plugin-cfg.xml.
[7/7/20 9:20:36:800 GMT] 0000004b com.ibm.ws.session.WASSessionCore                            I SESN0176I: A new session context will be created for application key default_host/cics-java-liberty-springboot-jcics-ding
[7/7/20 9:20:36:801 GMT] 0000004b com.ibm.ws.util                                              I SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[7/7/20 9:20:37:064 GMT] 0000004b com.ibm.ws.webcontainer.webapp                               I SRVE0292I: Servlet Message - [cics-java-liberty-springboot-jcics-0.1.0]:.2 Spring WebApplicationInitializers detected on cla
sspath
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O   .   ____          _            __ _ _
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O   '  |____| .__|_| |_|_| |_\__, | / / / /
[7/7/20 9:20:37:973 GMT] 0000004b SystemOut                                                    O  =========|_|==============|___/=/_/_/_/
[7/7/20 9:20:37:974 GMT] 0000004b SystemOut                                                    O  :: Spring Boot ::        (v2.3.0.RELEASE)
[7/7/20 9:20:38:131 GMT] 0000004b SystemOut                                                    O 2020-07-07 09:20:38.128  INFO 83952403 --- [RVICE_Thread-28] c.i.c.s.jcics.ServletInitializer         : Starting ServletInit
ializer on etp1.tsc.ibm.com with PID 83952403 (/var/cicsts/cicsts56/CT56B4A1/work/CT56B4A1/DFHWLP/wlp/usr/servers/defaultServer/installedApps/cics-java-liberty-springboot-jcics-0.1.0.war started by STCUSR in /ETP1/var/cic
sts/cicsts56/CT56B4A1/work)
[7/7/20 9:20:38:133 GMT] 0000004b SystemOut                                                    O 2020-07-07 09:20:38.133  INFO 83952403 --- [RVICE_Thread-28] c.i.c.s.jcics.ServletInitializer         : No active profile se
t, falling back to default profiles: default
[7/7/20 9:20:38:446 GMT] 00000053 com.ibm.ws.config.xml.internal.ConfigRefresher               A CWWKG0016I: Starting server configuration update.
[7/7/20 9:20:38:448 GMT] 00000053 com.ibm.ws.config.xml.internal.XMLConfigParser               A CWWKG0028A: Processing included configuration resource: /var/cicsts/cicsts56/CT56B4A1/work/CT56B4A1/DFHWLP/wlp/usr/servers/d
efaultServer/installedApps.xml
[7/7/20 9:20:38:450 GMT] 00000053 com.ibm.ws.config.xml.internal.ConfigRefresher               A CWWKG0018I: The server configuration was not updated. No functional changes were detected.
[7/7/20 9:20:39:214 GMT] 0000004b com.ibm.ws.webcontainer.webapp                               I SRVE0292I: Servlet Message - [cics-java-liberty-springboot-jcics-0.1.0]:.Initializing Spring embedded WebApplicationContext
[7/7/20 9:20:39:214 GMT] 0000004b SystemOut                                                    O 2020-07-07 09:20:39.214  INFO 83952403 --- [RVICE_Thread-28] o.s.web.context.ContextLoader            : Root WebApplicationC
ontext: initialization completed in 1011 ms
[7/7/20 9:20:39:608 GMT] 0000004b SystemOut                                                    O 2020-07-07 09:20:39.608  INFO 83952403 --- [RVICE_Thread-28] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing Executo
rService 'applicationTaskExecutor'
[7/7/20 9:20:39:847 GMT] 0000004b SystemOut                                                    O 2020-07-07 09:20:39.846  INFO 83952403 --- [RVICE_Thread-28] c.i.c.s.jcics.ServletInitializer         : Started ServletIniti
alizer in 2.638 seconds (JVM running for 3347.897)
[7/7/20 9:25:53:853 GMT] 00000045 com.ibm.ws.webcontainer.webapp                               I SRVE0292I: Servlet Message - [cics-java-liberty-springboot-jcics-0.1.0]:.Initializing Spring DispatcherServlet 'dispatcherSe
rvlet'
[7/7/20 9:25:53:853 GMT] 00000045 SystemOut                                                    O 2020-07-07 09:25:53.853  INFO 83952403 --- [HP.TASK205.CJSA] o.s.web.servlet.DispatcherServlet        : Initializing Servlet
 'dispatcherServlet'
[7/7/20 9:25:53:863 GMT] 00000045 SystemOut                                                    O 2020-07-07 09:25:53.863  INFO 83952403 --- [HP.TASK205.CJSA] o.s.web.servlet.DispatcherServlet        : Completed initializa
tion in 10 ms
[7/7/20 9:25:53:863 GMT] 00000045 com.ibm.ws.webcontainer.servlet                              I SRVE0242I: [cics-java-liberty-springboot-jcics-0.1.0] [/cics-java-liberty-springboot-jcics-ding] [dispatcherServlet]: Initia
lization successful.
```

## アプリ稼働確認

先の例と同様、ブラウザからTSQに書き込むアプリを実行してみます。今度は書き込む文字列を"ILOVECICS2"にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ef085e86-264b-12de-627c-14fe2b70e785.png)
正常に結果が返りました。
CICS端末からCEBRで確認すると、きちんとデータが書き込まれていることが確認できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/caef1c54-38b4-0c23-305c-2d81f276f780.png)


# サンプルのカスタマイズ

CICS TS V5.5 + APAR PH14856 or V5.6 base では、Spring Bootアプリを従来のCICSプログラムのように扱うことができるようになるため、EXEC CICS LINKでSpring Bootプログラムを呼び出したり、EXEC CICS STARTで呼び出すことができるようになります。
参考: [Linking to a Java EE or Spring Boot application from a CICS program](https://www.ibm.com/support/knowledgecenter/SSGMCP_5.6.0/applications/developing/java/link_2_liberty.html)

ここでは、COBOLなどの言語からEXEC CICS LINK でSpring Bootアプリを呼び出すシナリオを試してみます。
EXEC CICS LINK でSpring Bootアプリを呼び出す際、データの受け渡しはChannel & Containerを使いますが、今回は簡素化のためデータ受け渡しは行わずに単純にプログラム呼び出しの部分のみ追加実装して試してみます。

## server.xml変更
Liberty上のプログラムを呼び出す構成を行う場合、ランタイムとなるLibertyのフィーチャーとして`cicsts:link-1.0`を追加する必要があります。以下のようにfeatureを追加してJVMServerを再起動(Disabled=>Enabled)しておきます。

```xml:server.xml
...
    <featureManager>
        <feature>cicsts:core-1.0</feature>
        <feature>cicsts:defaultApp-1.0</feature>
        <feature>jsp-2.3</feature>
        <feature>wab-1.0</feature>
        <feature>transportSecurity-1.0</feature>
        <feature>cicsts:link-1.0</feature>
    </featureManager>
...
```

## サンプルプロジェクトをEclipseへ取り込む

上で取り扱ったGitHubで提供されているサンプルプロジェクトをEclipseに取り込みます。ここではCICS Explorerとして提供されているEclipseを使います。

Eclipse Marketplaceから、Buildship Gradle Integrationをインストールしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ca04600b-3d5e-acef-24ed-231f65dc8b28.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ae9af268-bb88-ac43-d00f-2f71767064c7.png)


Javaパースペクティブのパッケージ・エクスプローラー・ビューで、右クリック - インポート - フォルダまたはアーカイブからのプロジェクト で、cloneしたプロジェクトのディレクトリを選択して取り込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/881230bd-387c-5d02-bf33-7ec388e54621.png)

取り込み後は赤×がついてエラー表示になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/2ac8d8ee-1a97-3608-f504-f111141fd1d9.png)

プロジェクト右クリック - Gradle - Refresh Gradle Project
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/07d6315d-90f0-6330-a602-1ed2fbbf96bd.png)

エラーが消えました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/aad554c7-84ea-f33a-8c33-e85078d393f1.png)

## ロジック追加

まず、build.gradleに依存関係を追加します。dependenciesに以下を追加します。

```gradle:build.gradle
...
dependencies 
{
   ...
    // for @CICSProgram annotation
    compileOnly ("com.ibm.cics:com.ibm.cics.server.invocation.annotations")
    annotationProcessor ("com.ibm.cics:com.ibm.cics.server.invocation:5.6")
}
```

Refresh Gradle Projectを実行しておきます。

WriteTSQController.javaと同じパッケージに、以下のファイルを作成します。

```java:WriteTSQLinked.java
package com.ibm.cicsdev.springboot.jcics;

import org.springframework.stereotype.Component;
import com.ibm.cics.server.CicsConditionException;
import com.ibm.cics.server.TSQ;
import com.ibm.cics.server.invocation.CICSProgram;

@Component
public class WriteTSQLinked {
	
    @CICSProgram("WRTTSQ")
    public void writeTSQlinked()
    {     
		String tsqName = "SPGJCICS";
		String record  = "ILOVECICS3";

		// Write to the TSQ
		try {
			// Construct the TSQ object
			TSQ tsqQ = new TSQ();
			tsqQ.setName(tsqName);

			// write the record to the TSQ
			tsqQ.writeString(record);		
			
		} catch ( CicsConditionException  e) {
			// Print the stack trace
			e.printStackTrace();
		}
    }
}
```

`@CICSProgram`アノテーションで、直後のメソッドを"WRTTSQ"という名前のCICSプログラムとして認識させています。
CICSプログラムとして認識させる場合、メソッドはpublic指定、引数なしで定義する必要があります。
今回は引数なしで、埋め込みでSPGJCICSというTSQにILOVECICS3という値を書き出すロジックを追加しています。

## ビルド/デプロイ

```
C:\y\workspace\cicsts56\cics-springboot02>gradlew bootWar

BUILD SUCCESSFUL in 7s
2 actionable tasks: 2 executed
```

```
C:\y\workspace\cicsts56\cics-springboot02>gradlew deployCICSBundle

> Task :cics-springboot-bundle04:buildCICSBundle
Adding Java-based bundle parts from 'cicsBundlePart' dependency configuration
Adding Java-based bundle part: 'C:\y\workspace\cicsts56\cics-springboot02\cics-java-liberty-springboot-jcics\build\libs\cics-java-liberty-springboot-jcics-0.1.0.war'
Adding non-Java-based bundle parts from 'src/main/resources'

> Task :cics-springboot-bundle04:deployCICSBundle
Task deployCICSBundle

BUILD SUCCESSFUL in 1m 31s
4 actionable tasks: 3 executed, 1 up-to-date
```

完了すると、バンドルがインストールされ、WARがバンドルパーツとしてインストールされます。さらに、そこに含まれる`@CICSProgram`で指定したメソッドがCICSプログラムとして認識されるため、CICSプログラム"WRTTSQ"がインストールされた状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/e692eef0-9ea1-ad67-2faa-1a4a6c3ae66d.png)

インストールされたプログラム定義の詳細はこんな感じ(CICS Explorerで確認)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/1d4af0e1-8637-8488-aad8-83de72fed599.png)

ターゲットのリージョンのJOBLOGにはこんな感じのメッセージが出ています。

```
DFHRL0107 I 07/08/2020 15:40:30 CT56B4A1 CICSUSER The CICS resource lifecycle manager has started to create the BUNDLE resource    
           SPBBUNDL.                                                                                                               
DFHRL0125 I 07/08/2020 15:40:30 CT56B4A1 CICSUSER BUNDLE resource SPBBUNDL is being created with BUNDLEID cics-springboot-bundle04 
           and version 1.0.0.                                                                                                      
DFHSJ1105 07/08/2020 15:40:30 CT56B4A1 WAR bundle cics-java-liberty-springboot-jcics-0.1.0 version 1.0.0 from BUNDLE SPBBUNDL has  
           been installed as Disabled.                                                                                             
DFHRL0108 I 07/08/2020 15:40:30 CT56B4A1 CONL The CICS resource lifecycle manager is in the process of creating the BUNDLE resource
           SPBBUNDL and the BUNDLE is in the enabling state.                                                                       
DFHRD0128 I 07/08/2020 15:40:30 CT56B4A1  CICSUSER CONL INSTALL BUNDLE(SPBBUNDL)                                                   
???? ??? CONL CICSUSER 07/08/20 15:40:30 INSTALL BUNDLE(SPBBUNDL) GROUP(TAGGRP)                                                    
DFHFC0961 07/08/2020 15:40:30 CT56B4A1 Calculation of LSR pool 1 parameters incomplete. Filename DFHDBFK has no DSNAME.            
DFHPG0101 07/08/2020 15:40:34 CT56B4A1  CICSUSER CJSP Resource definition for WRTTSQ has been added.                               
DFHSJ1204 07/08/2020 15:40:34 CT56B4A1 A linkable service has been registered for program WRTTSQ in JVMSERVER DFHWLP with classname
           com.ibm.cicsdev.springboot.jcics.WriteTSQLinked, method writeTSQlinked.                                                 
DFHSJ1107 07/08/2020 15:40:34 CT56B4A1 WAR bundle with symbolic name cics-java-liberty-springboot-jcics-0.1.0 version 1.0.0 has bee
           Enabled.                                                                                                                
DFHRL0132 I 07/08/2020 15:40:34 CT56B4A1 CJSL All defined resources for BUNDLE SPBBUNDL are now in the enabled state.              
DFHAP1900 07/08/2020 15:40:40 CT56B4A1 NONE CICSUSER CONL SET BUNDLE(SPBBUNDL) ENABLESTATUS(ENABLED) RESP(NORMAL) RESP2(0).        
```

## アプリ稼働確認

簡易的にCICS端末から`CECI LINK PROGRAM(WRTTSQ)'発行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/5f60c6bd-a3b7-967b-2c19-e3bf31b5b8b1.png)

CEBRでTSQ"SPGJCICS"の中身を確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/594bddcb-a275-f646-c789-6d9a0638e9f7.png)

期待したメッセージが書き込まれています！
これで、EXEC CICS LINKを使用してSpring Bootアプリを呼び出す流れが確認できました！