Websphere Application ServerのAdminConfig

# AdminConfigの使いかたまとめ
WASの設定情報をwsadminで取得・変更する際に使用するAdminConfigオブジェクトの概要と使いかたの覚書。

## 用語（AdminConfigオブジェクトの概念）

### オブジェクトタイプ
XML構成ファイルに基づくオブジェクトのタイプ（文字列）。
`AdminConfig.types()`で確認可能。
`wsadmin.sh -conntype NONE -c "print(AdminConfig.types())" | grep -c -v "^WASX7357I"`として調べると、860種類のオブジェクトタイプが存在する（version 9.0.0.9）。

#### 例
+ DataSource
+ Application
+ ApplicationServer

### 構成ID
オブジェクトを示すID。
`AdminConfig.list()`等で確認可能。
たとえば全てのオブジェクトの構成IDを取得したければ、以下のようにする。

```python:wsadmin
all_types = AdminConfig.types()
type_list = all_types.split("\n")
for type_str in type_list:
    print(AdminConfig.list(type_str))
```

#### 例
+ ApplicationServer: u'(cells/devAppCell/nodes/app/servers/apserver|server.xml#ApplicationServer_1183122130078)'
+ DataSource: u'"DefaultApp Datasource(cells/devAppCell/nodes/app/servers/apserver|resources.xml#DataSource_1183122153625)"\nDefaultEJBTimerDataSource(cells/devAppCell/nodes/app/servers/apserver|resources.xml#DataSource_1000001)\nbuilt-in-derby-datasource(cells/devAppCell|resources.xml#DataSource_9007001)\ndb2Hadrdb(cells/devAppCell/nodes/app/servers/apserver|resources.xml#DataSource_1544617692932)'

## 主要メソッド
### `types()`
オブジェクトタイプを返す（改行区切りの文字列）。
オプション引数で正規表現によるフィルタリングが可能。
例えば、"Server"または"server"文字列を含むオブジェクトタイプを調べるには、`AdminConfig.types(".*[Ss]erver.*")`とすればよい。

### `list()`
オブジェクトタイプ文字列を引数に取り、そのオブジェクトタイプに所属するオブジェクトのリスト（構成IDのリスト）を返す（改行区切りの文字列）。

### `getid()`
対象のパスを引数に取り、オブジェクトの構成IDを返す（抑制パスと呼ばれる簡易的なパスから正式な構成IDを取得する）。

### `getObjectName()`
構成IDを引数に取り、そのオブジェクトの名前を返す。

### `getObjectType()`
構成IDを引数に取り、そのオブジェクトのオブジェクトタイプを返す。

### `parents()`
オブジェクトタイプ文字列を引数に取り、そのオブジェクトタイプの親のオブジェクトタイプ文字列を返す。

### `required()`
オブジェクトタイプ文字列を引数に取り、含まれる必須属性を表示する。

### `show()`
構成IDを引数に取り、含まれる属性を表示する。

### `showall()`
構成IDを引数に取り、含まれる属性を再帰的に返す。

### `showAttribute()`
構成IDと属性名を引数に取り、当該属性の値を返す。

# working with AdminConfig
## Webコンテナの設定情報を調べる
### オブジェクトタイプ名を調べる
```python:wsadmin
print(AdminConfig.types("^Web.*"))
```

"WebContainer"だとわかる（容易に推測可能）。なお、この名前は管理コンソール、つまりWEBコンソール上の表示と同じでなくてよい、とマニュアルには書かれている。
<img width="878" alt="89341AED-1E13-4494-AA0B-31A143D4D39F.png" src="https://qiita-image-store.s3.amazonaws.com/0/232587/b99d3ed9-9682-4cb7-6a02-cca7908353c3.png">
この場合、"Web container"が該当すると思われるが、この値は使用できない。
WEBコンソールと同じではない、というのが正解のようだ。。。

### 構成IDを調べる
```python:wsadmin
web_container_cfg_id = AdminConfig.list("WebContainer")
print(web_container_cfg_id)
```

### 設定を確認する
```python:wsadmin
print(AdminConfig.showall(web_container_cfg_id))
```

```text:結果抜粋（改行およびインデントを付与）
[apiDiscovery false]
[asyncIncludeTimeout 60000]
[components []]
[parentComponent (cells/devAppCell/nodes/app/servers/apserver|server.xml#ApplicationServer_1183122130078)]
[services
  [
    [
      [defaultCookieSettings
        [
          [httpOnly true]
          [name JSESSIONID]
        ]
      ]
      [enable true]
      [enableCookies true]
      [sessionDatabasePersistence
        [
          [datasourceJNDIName jdbc/Sessions]
          [tableSpaceName []]
        ]
      ]
      [sessionPersistenceMode NONE]
      [tuningParams
        [
          [invalidationSchedule
            [
              [firstHour 14]
              [secondHour 2]
            ]
          ]
          [invalidationTimeout 30]
        ]
      ]
    ]
  ]
]
[sessionAffinityTimeout 0]
[stateManagement
  [
    [initialState START]
    [managedObject (cells/devAppCell/nodes/app/servers/apserver|server.xml#WebContainer_1183122130078)]
  ]
]
[transports []]
[useAsyncRunnableWorkManager true]
```
独特なノーテーションで出力される。元はXMLなのでそれよりは読みやすいかもしれない。JSONに近いように見えなくもない。なにか決まった呼び方がある由緒ある記述方式なのか（そしていい感じのパーサがある？）？？？
もっとも、これ専用のパーサを考えるくらいなら、XMLパーサを使って直接元ファイルを読み込んだ方が話は早い。あくまでもCUIで手軽に確認できる、そしてプレインなテキストに落とせるのがありがたいと思っておくのが吉。

## 特定のオブジェクトタイプがどの構成ファイルに定義されているか調べる
例えばJVMの引数設定を誤ったせいで起動しなくなったときなどに使える。

```bash
wsadmin.sh -conntype none -c "print(AdminConfig.list('JavaVirtualMachine'))"
```

※起動していない前提なので"-conntype none"でローカルモードとして実行

```text:出力例
(cells/devAppCell/nodes/app/servers/apserver|server.xml#JavaVirtualMachine_1183122130078)
```

"${PROFILE_ROOT}/config/cells/~略~/server.xml"をみればよいのだとあたりがつく。
これを直接編集するか、またはせっかくなのでこのままwsadminで修正する。

```python:wsadmin
jvm = AdminConfig.list('JavaVirtualMachine')
# 一応内容確認
print(AdminConfig.show(jvm))
# 属性変更
AdminConfig.modify(jvm, [["genericJvmArguments", "-Xms:100m"]])
# 汎用JVM引数リセット（再設定）
AdminConfig.resetAttributes(jvm, [["genericJvmArguments", "-Xms:100m"]])
# またはデフォルトに戻す
AdminConfig.unsetAttributes(jvm, "genericJvmArguments")
# 修正後確認
print(AdminConfig.show(jvm))
# 保存
AdminConfig.save()
```

## 全ての属性（つまりConfiguration）を文字列表現で出力する
```python
# 全てのオブジェクトタイプをリストに取得
all_types = AdminConfig.types().split("\n")
# 全てのオブジェクトタイプについて、所属するオブジェクトの構成IDを取得
for type_str in all_types:
    print("Object type: " + type_str)
    all_config_ids = AdminConfig.list(type_str).split("\n")            
    # 全ての構成IDについて含まれる属性を再帰的に出力
    for config_id in all_config_ids:
        print("Configuration ID: " + config_id)
        if(config_id != ""):
            print(AdminConfig.showall(config_id))
```

# 参考資料
[IBM Knowledge Center: AdminConfig](https://www.ibm.com/support/knowledgecenter/ja/SSEQTP_9.0.0/com.ibm.websphere.base.doc/ae/rxml_adminconfig1.html)