diff --git a/site/src/site/sphinx/_include_html/arthas-tutorials.html b/site/src/site/sphinx/_include_html/arthas-tutorials.html
index d17e6b92b..54d446fc6 100644
--- a/site/src/site/sphinx/_include_html/arthas-tutorials.html
+++ b/site/src/site/sphinx/_include_html/arthas-tutorials.html
@@ -713,6 +713,18 @@
cn: "case-web-console-cn",
}
},
+ {
+ id: "case-http-api",
+ type: "USERCASE",
+ names: {
+ en: "Http API",
+ cn: "Http API",
+ },
+ ids: {
+ en: "case-http-api-en",
+ cn: "case-http-api-cn",
+ }
+ },
{
id: "case-save-log",
type: "USERCASE",
diff --git a/site/src/site/sphinx/en/http-api.md b/site/src/site/sphinx/en/http-api.md
index e052ae5bb..4c95844b7 100644
--- a/site/src/site/sphinx/en/http-api.md
+++ b/site/src/site/sphinx/en/http-api.md
@@ -1,6 +1,8 @@
Http API
========
+[`Http API` online tutorial](https://arthas.aliyun.com/doc/arthas-tutorials.html?language=en&id=case-http-api)
+
### Overview
Http API provides a RESTful-like interactive interface, and both
diff --git a/site/src/site/sphinx/http-api.md b/site/src/site/sphinx/http-api.md
index 8119915cb..4ff6e0ece 100644
--- a/site/src/site/sphinx/http-api.md
+++ b/site/src/site/sphinx/http-api.md
@@ -1,6 +1,8 @@
Http API
========
+[`Http API`在线教程](https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn&id=case-http-api)
+
### 概览
Http API
diff --git a/tutorials/katacoda/case-http-api-cn/arthas-boot.md b/tutorials/katacoda/case-http-api-cn/arthas-boot.md
new file mode 100644
index 000000000..84ef525a2
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/arthas-boot.md
@@ -0,0 +1,16 @@
+
+
+
+
+在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动:
+
+`wget https://alibaba.github.io/arthas/arthas-boot.jar
+java -jar arthas-boot.jar`{{execute T2}}
+
+`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。
+
+选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`:
+
+Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。
+
+
diff --git a/tutorials/katacoda/case-http-api-cn/arthas-demo.md b/tutorials/katacoda/case-http-api-cn/arthas-demo.md
new file mode 100644
index 000000000..f1136e88e
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/arthas-demo.md
@@ -0,0 +1,10 @@
+
+
+
+
+下载`arthas-demo.jar`,再用`java -jar`命令启动:
+
+`wget https://alibaba.github.io/arthas/arthas-demo.jar
+java -jar arthas-demo.jar`{{execute T1}}
+
+`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。
diff --git a/tutorials/katacoda/case-http-api-cn/classpath-java-app.md b/tutorials/katacoda/case-http-api-cn/classpath-java-app.md
new file mode 100644
index 000000000..1c8a39f86
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/classpath-java-app.md
@@ -0,0 +1,30 @@
+
+通过Http api查询Java应用的System properties,提取`java.class.path`的值。
+
+`json_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"exec",
+ "command":"sysprop"
+}')`{{execute T3}}
+
+* 使用`sed`提取值:
+
+`class_path=$(echo $json_data | tr -d '\n' | sed 's/.*"java.class.path":"\([^"]*\).*/\1/')
+echo "classpath: $class_path"`{{execute T3}}
+
+* 使用`json_pp/awk`提取值
+
+`class_path=$(echo $json_data | tr -d '\n' | json_pp | grep java.class.path | awk -F'"' '{ print $4 }')
+echo "classpath: $class_path"`{{execute T3}}
+
+输出内容:
+
+```
+classpath: arthas-demo.jar
+```
+
+注意:
+
+* `echo $json_data | tr -d '\n'` : 删除换行符(`line.separator`的值),避免影响`sed`/`json_pp`命令处理。
+* `awk -F'"' '{ print $4 }'` : 使用双引号作为分隔符号
+
diff --git a/tutorials/katacoda/case-http-api-cn/finish.md b/tutorials/katacoda/case-http-api-cn/finish.md
new file mode 100644
index 000000000..3a1483ad1
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/finish.md
@@ -0,0 +1,12 @@
+
+在“Http API”中,我们演示了了Arthas的Http API案例。如果有更多的技巧或者使用疑问,欢迎在Issue里提出。
+
+* Issues: https://github.com/alibaba/arthas/issues
+* 文档: https://alibaba.github.io/arthas
+
+
+如果您在使用Arthas,请让我们知道,您的使用对我们非常重要:[查看](https://github.com/alibaba/arthas/issues/111)
+
+欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。
+
+
\ No newline at end of file
diff --git a/tutorials/katacoda/case-http-api-cn/http-api.md b/tutorials/katacoda/case-http-api-cn/http-api.md
new file mode 100644
index 000000000..c60641591
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/http-api.md
@@ -0,0 +1,59 @@
+
+### 概览
+
+Http API
+提供类似RESTful的交互接口,请求和响应均为JSON格式的数据。相对于Telnet/WebConsole的输出非结构化文本数据,Http
+API可以提供结构化的数据,支持更复杂的交互功能,比如特定应用场景的一系列诊断操作。
+
+
+#### 访问地址
+
+Http API接口地址为:`http://ip:port/api`,必须使用POST方式提交请求参数。如POST
+`http://127.0.0.1:8563/api` 。
+
+注意:telnet服务的3658端口与Chrome浏览器有兼容性问题,建议使用http端口8563来访问http接口。
+
+#### 请求数据格式
+
+```json
+{
+ "action": "exec",
+ "requestId": "req112",
+ "sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb",
+ "consumerId": "955dbd1325334a84972b0f3ac19de4f7_2",
+ "command": "version",
+ "execTimeout": "10000"
+}
+```
+
+请求数据格式说明:
+
+* `action` : 请求的动作/行为,可选值请参考"请求Action"小节。
+* `requestId` : 可选请求ID,由客户端生成。
+* `sessionId` : Arthas会话ID,一次性命令不需要设置会话ID。
+* `consumerId` : Arthas消费者ID,用于多人共享会话。
+* `command` : Arthas command line 。
+* `execTimeout` : 命令同步执行的超时时间(ms),默认为30000。
+
+注意: 不同的action使用到参数不同,根据具体的action来设置参数。
+
+#### 请求Action
+
+目前支持的请求Action如下:
+
+* `exec` : 同步执行命令,命令正常结束或者超时后中断命令执行后返回命令的执行结果。
+* `async_exec` : 异步执行命令,立即返回命令的调度结果,命令执行结果通过`pull_results`获取。
+* `interrupt_job` : 中断会话当前的命令,类似Telnet `Ctrl + c`的功能。
+* `pull_results` : 获取异步执行的命令的结果,以http 长轮询(long-polling)方式重复执行
+* `init_session` : 创建会话
+* `join_session` : 加入会话,用于支持多人共享同一个Arthas会话
+* `close_session` : 关闭会话
+
+#### 响应状态
+
+响应中的state属性表示请求处理状态,取值如下:
+
+* `SCHEDULED`:异步执行命令时表示已经创建job并已提交到命令执行队列,命令可能还没开始执行或者执行中;
+* `SUCCEEDED`:请求处理成功(完成状态);
+* `FAILED`:请求处理失败(完成状态),通常附带message说明原因;
+* `REFUSED`:请求被拒绝(完成状态),通常附带message说明原因;
diff --git a/tutorials/katacoda/case-http-api-cn/index.json b/tutorials/katacoda/case-http-api-cn/index.json
new file mode 100644
index 000000000..f9535b927
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/index.json
@@ -0,0 +1,62 @@
+{
+ "title": "Arthas Http API案例",
+ "description": "Arthas Http API案例",
+ "difficulty": "精通者",
+ "time": "10-20 分钟",
+ "details": {
+ "steps": [
+ {
+ "title": "启动arthas demo",
+ "text": "arthas-demo.md"
+ },
+ {
+ "title": "启动arthas-boot",
+ "text": "arthas-boot.md"
+ },
+ {
+ "title": "Http API",
+ "text": "http-api.md"
+ },
+ {
+ "title": "一次性命令",
+ "text": "one-time-command.md"
+ },
+ {
+ "title": "会话交互",
+ "text": "session-interaction.md"
+ },
+ {
+ "title": "Web UI",
+ "text": "web-ui.md"
+ },
+ {
+ "title": "watch命令输出map对象",
+ "text": "watch-output-map.md"
+ },
+ {
+ "title": "获取Java应用的Classpath",
+ "text": "classpath-java-app.md"
+ }
+ ],
+ "intro": {
+ "text": "intro.md"
+ },
+ "finish": {
+ "text": "finish.md"
+ }
+ },
+ "environment": {
+ "uilayout": "terminal",
+ "showdashboard": true,
+ "dashboards": [
+ {
+ "name": "Web Port 8563",
+ "port": 8563
+ }
+ ]
+ },
+ "backend": {
+ "imageid": "java",
+ "environmentsprotocol": "http"
+ }
+}
\ No newline at end of file
diff --git a/tutorials/katacoda/case-http-api-cn/intro.md b/tutorials/katacoda/case-http-api-cn/intro.md
new file mode 100644
index 000000000..42c8c4618
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/intro.md
@@ -0,0 +1,23 @@
+
+
+
+
+
+`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。
+
+`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。
+
+当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
+
+- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
+- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
+- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
+- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
+- 是否有一个全局视角来查看系统的运行状况?
+- 有什么办法可以监控到JVM的实时运行状态?
+- 怎么快速定位应用的热点,生成火焰图?
+
+本教程会以一个简单的应用为例,演示http-api案例。
+
+* Github: https://github.com/alibaba/arthas
+* 文档: https://alibaba.github.io/arthas/
diff --git a/tutorials/katacoda/case-http-api-cn/one-time-command.md b/tutorials/katacoda/case-http-api-cn/one-time-command.md
new file mode 100644
index 000000000..2ed12bb74
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/one-time-command.md
@@ -0,0 +1,82 @@
+
+与执行批处理命令类似,一次性命令以同步方式执行。不需要创建会话,不需要设置`sessionId`选项。
+
+```json
+{
+ "action": "exec",
+ "command": ""
+}
+```
+
+比如获取Arthas版本号:
+
+`curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"exec",
+ "command":"version"
+}
+' | json_pp`{{execute T3}}
+
+响应内容如下:
+
+```json
+{
+ "state" : "SUCCEEDED",
+ "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869",
+ "body" : {
+ "results" : [
+ {
+ "type" : "version",
+ "version" : "3.3.7",
+ "jobId" : 5
+ },
+ {
+ "jobId" : 5,
+ "statusCode" : 0,
+ "type" : "status"
+ }
+ ],
+ "timeExpired" : false,
+ "command" : "version",
+ "jobStatus" : "TERMINATED",
+ "jobId" : 5
+ }
+}
+```
+
+响应数据解析:
+
+* `state`: 请求处理状态,参考“接口响应状态”说明
+* `sessionId `: Arthas会话ID,一次性命令自动创建及销毁临时会话
+* `body.jobId`: 命令的任务ID,同一任务输出的所有Result都是相同的jobId
+* `body.jobStatus`: 任务状态,同步执行正常结束为`TERMINATED `
+* `body.timeExpired`: 任务执行是否超时
+* `body/results`: 命令执行的结果列表
+
+**命令结果格式说明**
+
+```json
+ [{
+ "type" : "version",
+ "version" : "3.3.7",
+ "jobId" : 5
+ },
+ {
+ "jobId" : 5,
+ "statusCode" : 0,
+ "type" : "status"
+ }]
+```
+
+* `type` : 命令结果类型,除了`status`等特殊的几个外,其它的保持与Arthas命令名称一致。请参考"特殊命令结果"小节。
+* `jobId` : 处理命令的任务ID。
+* 其它字段为每个不同命令的数据。
+
+注意:也可以使用一次性命令的方式执行watch/trace等连续输出的命令,但不能中断命令执行,可能出现长时间没有结束的问题。请参考"watch命令输出map对象"小节的示例。
+
+请尽量按照以下方式处理:
+
+* 设置合理的`execTimeout`,到达超时时间后强制中断命令执行,避免长时间挂起。
+* 通过`-n`参数指定较少的执行次数。
+* 保证命令匹配的方法可以成功命中和condition-express编写正确,如果watch/trace没有命中就算指定`-n
+ 1`也会挂起等待到执行超时。
diff --git a/tutorials/katacoda/case-http-api-cn/session-interaction.md b/tutorials/katacoda/case-http-api-cn/session-interaction.md
new file mode 100644
index 000000000..434272938
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/session-interaction.md
@@ -0,0 +1,305 @@
+
+由用户创建及管理Arthas会话,适用于复杂的交互过程。访问流程如下:
+
+* 创建会话
+* 加入会话(可选)
+* 拉取命令结果
+* 执行一系列命令
+* 中断命令执行
+* 关闭会话
+
+#### 创建会话
+
+创建会话, 保存输出到bash环境变量
+
+`session_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"init_session"
+}
+')
+echo $session_data | json_pp`{{execute T3}}
+
+注: `json_pp` 工具将输出内容格式化为pretty json。
+
+响应结果:
+
+```json
+{
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1",
+ "state" : "SUCCEEDED"
+}
+```
+
+提取会话ID和消费者ID。
+
+当前会话ID为:
+
+`session_id=$(echo $session_data | sed 's/.*"sessionId":"\([^"]*\)".*/\1/g')
+echo $session_id`{{execute T3}}
+
+`b09f1353-202c-407b-af24-701b744f971e`;
+
+当前消费者ID为:
+
+`consumer_id=$(echo $session_data | sed 's/.*"consumerId":"\([^"]*\)".*/\1/g')
+echo $consumer_id`{{execute T3}}
+
+`5ae4e5fbab8b4e529ac404f260d4e2d1_1 `。
+
+#### 加入会话
+
+指定要加入的会话ID,服务端将分配一个新的消费者ID。多个消费者可以接收到同一个会话的命令结果。本接口用于支持多人共享同一个会话或刷新页面后重新拉取会话历史记录。
+
+加入会话,保存输出到bash环境变量
+
+`session_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"join_session",
+ "sessionId" : "'"$session_id"'"
+}
+')
+echo $session_data | json_pp`{{execute T3}}
+
+响应结果:
+
+```json
+{
+ "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "state" : "SUCCEEDED"
+}
+```
+
+提取消费者ID。
+
+新的消费者ID为
+
+`consumer_id=$(echo $session_data | sed 's/.*"consumerId":"\([^"]*\)".*/\1/g')
+echo $consumer_id`{{execute T3}}
+
+`8f7f6ad7bc2d4cb5aa57a530927a95cc_2 ` 。
+
+#### 拉取命令结果
+
+拉取命令结果消息的action为`pull_results`。请使用Http long-polling方式,定时循环拉取结果消息。
+消费者的超时时间为5分钟,超时后需要调用`join_session`分配新的消费者。每个消费者单独分配一个缓存队列,按顺序拉取命令结果,不会影响到其它消费者。
+
+请求参数需要指定会话ID及消费者ID:
+
+`curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"pull_results",
+ "sessionId" : "'"$session_id"'",
+ "consumerId" : "'"$consumer_id"'"
+}
+' | json_pp`{{execute T3}}
+
+用Bash脚本定时拉取结果消息:
+
+`while true; do curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"pull_results",
+ "sessionId" : "'"$session_id"'",
+ "consumerId" : "'"$consumer_id"'"
+}
+' | json_pp; sleep 2; done`{{execute T4}}
+
+响应内容如下:
+
+```json
+{
+ "body" : {
+ "results" : [
+ {
+ "inputStatus" : "DISABLED",
+ "jobId" : 0,
+ "type" : "input_status"
+ },
+ {
+ "type" : "message",
+ "jobId" : 0,
+ "message" : "Welcome to arthas!"
+ },
+ {
+ "tutorials" : "https://arthas.aliyun.com/doc/arthas-tutorials.html",
+ "time" : "2020-08-06 15:56:43",
+ "type" : "welcome",
+ "jobId" : 0,
+ "pid" : "7909",
+ "wiki" : "https://arthas.aliyun.com/doc",
+ "version" : "3.3.7"
+ },
+ {
+ "inputStatus" : "ALLOW_INPUT",
+ "type" : "input_status",
+ "jobId" : 0
+ }
+ ]
+ },
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
+ "state" : "SUCCEEDED"
+}
+
+```
+
+
+#### 异步执行命令
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"async_exec",
+ "command":"watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" ",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+`async_exec` 的结果:
+
+```json
+{
+ "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
+ "state" : "SCHEDULED",
+ "body" : {
+ "jobStatus" : "READY",
+ "jobId" : 3,
+ "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
+ }
+}
+```
+
+* `state` : `SCHEDULED` 状态表示已经解析命令生成任务,但未开始执行。
+* `body.jobId` :
+ 异步执行命令的任务ID,可以根据此任务ID来过滤在`pull_results`输出的命令结果。
+* `body.jobStatus` : 任务状态`READY`表示未开始执行。
+
+
+切换到上面自动拉取结果消息脚本的shell(Terminal 4),查看输出:
+
+```json
+{
+ "body" : {
+ "results" : [
+ {
+ "type" : "command",
+ "jobId" : 3,
+ "state" : "SCHEDULED",
+ "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
+ },
+ {
+ "inputStatus" : "ALLOW_INTERRUPT",
+ "jobId" : 0,
+ "type" : "input_status"
+ },
+ {
+ "success" : true,
+ "jobId" : 3,
+ "effect" : {
+ "listenerId" : 3,
+ "cost" : 24,
+ "classCount" : 1,
+ "methodCount" : 1
+ },
+ "type" : "enhancer"
+ },
+ {
+ "sizeLimit" : 10485760,
+ "expand" : 1,
+ "jobId" : 3,
+ "type" : "watch",
+ "cost" : 0.071499,
+ "ts" : 1596703453237,
+ "value" : [
+ [
+ -170365
+ ],
+ null,
+ {
+ "stackTrace" : [
+ {
+ "className" : "demo.MathGame",
+ "classLoaderName" : "app",
+ "methodName" : "primeFactors",
+ "nativeMethod" : false,
+ "lineNumber" : 46,
+ "fileName" : "MathGame.java"
+ },
+ ...
+ ],
+ "localizedMessage" : "number is: -170365, need >= 2",
+ "@type" : "java.lang.IllegalArgumentException",
+ "message" : "number is: -170365, need >= 2"
+ }
+ ]
+ },
+ {
+ "type" : "watch",
+ "cost" : 0.033375,
+ "jobId" : 3,
+ "ts" : 1596703454241,
+ "value" : [
+ [
+ 1
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 13,
+ 491
+ ],
+ null
+ ],
+ "sizeLimit" : 10485760,
+ "expand" : 1
+ }
+ ]
+ },
+ "consumerId" : "8ecb9cb7c7804d5d92e258b23d5245cc_1",
+ "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
+ "state" : "SUCCEEDED"
+}
+```
+
+watch命令结果的`value`为watch-experss的值,上面命令中为`{params, returnObj,
+throwExp}`,所以watch结果的value为一个长度为3的数组,每个元素分别对应相应顺序的表达式。
+请参考"watch命令输出map对象"小节。
+
+#### 中断命令执行
+
+中断会话正在运行的前台Job(前台任务):
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"interrupt_job",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+```json
+{
+ "state" : "SUCCEEDED",
+ "body" : {
+ "jobStatus" : "TERMINATED",
+ "jobId" : 3
+ }
+}
+```
+
+#### 关闭会话
+指定会话ID,关闭会话。
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"close_session",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+```json
+{
+ "state" : "SUCCEEDED"
+}
+```
diff --git a/tutorials/katacoda/case-http-api-cn/watch-output-map.md b/tutorials/katacoda/case-http-api-cn/watch-output-map.md
new file mode 100644
index 000000000..3d1cf2959
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/watch-output-map.md
@@ -0,0 +1,87 @@
+
+watch的结果值由计算`watch-express` ognl表达式产生,可以通过改变ognl表达式来生成想要的值,请参考[OGNL文档](https://commons.apache.org/proper/commons-ognl/language-guide.html)。
+
+> Maps can also be created using a special syntax.
+>
+>#{ "foo" : "foo value", "bar" : "bar value" }
+>
+>This creates a Map initialized with mappings for "foo" and "bar".
+
+下面的命令生成map格式的值:
+
+```bash
+watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5
+```
+
+在Telnet shell/WebConsole 中执行上面的命令,输出的结果:
+
+```bash
+ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[
+ @String[params]:@Object[][
+ @Integer[1],
+ ],
+ @String[returnObj]:@ArrayList[
+ @Integer[2],
+ @Integer[241],
+ @Integer[379],
+ ],
+ @String[throwExp]:null,
+]
+```
+
+用Http api 执行上面的命令,注意对JSON双引号转义:
+
+`curl -Ss -XPOST http://localhost:8563/api -d @- << EOF
+{
+ "action":"exec",
+ "execTimeout": 30000,
+ "command":"watch *MathGame prime* '#{ \"params\" : params, \"returnObj\" : returnObj, \"throwExp\": throwExp}' -n 3 "
+}
+EOF`{{execute T3}}
+
+Http api 执行结果:
+
+```json
+{
+ "body": {
+ ...
+ "results": [
+ ...
+ {
+ ...
+ "type": "watch",
+ "value": {
+ "params": [
+ 1
+ ],
+ "returnObj": [
+ 2,
+ 5,
+ 17,
+ 23,
+ 23
+ ]
+ }
+ },
+ {
+ ...
+ "type": "watch",
+ "value": {
+ "params": [
+ -98278
+ ],
+ "throwExp": {
+ "@type": "java.lang.IllegalArgumentException",
+ "localizedMessage": "number is: -98278, need >= 2",
+ "message": "number is: -98278, need >= 2",
+ "stackTrace": [
+ ...
+ ]
+ }
+ }
+ },
+ ...
+}
+```
+
+可以看到watch结果的value变成map对象,程序可以通过key读取结果。
diff --git a/tutorials/katacoda/case-http-api-cn/web-ui.md b/tutorials/katacoda/case-http-api-cn/web-ui.md
new file mode 100644
index 000000000..48e3efd25
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-cn/web-ui.md
@@ -0,0 +1,19 @@
+
+
+
+一个基于Http API接口实现的Web UI,访问地址为: https://[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com/ui 。
+
+已实现功能:
+
+* 创建会话
+* 复制并打开url加入会话,多人共享会话
+* 周期性拉取会话命令结果消息
+* 刷新页面或者加入会话拉取会话历史命令消息
+* 输入命令/中断命令状态控制
+
+待开发功能:
+
+* 改进将命令结果消息可读性
+* 命令输入支持自动完成及命令模板
+* 提供命令帮助
+* 支持个人选项设置
diff --git a/tutorials/katacoda/case-http-api-en/arthas-boot.md b/tutorials/katacoda/case-http-api-en/arthas-boot.md
new file mode 100644
index 000000000..b9f9cc04f
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/arthas-boot.md
@@ -0,0 +1,16 @@
+
+
+
+
+In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command:
+
+`wget https://alibaba.github.io/arthas/arthas-boot.jar
+java -jar arthas-boot.jar`{{execute T2}}
+
+`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed.
+
+Select the first process, type `1`{{execute T2}} ,then type `Enter`:
+
+After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help.
+
+
diff --git a/tutorials/katacoda/case-http-api-en/arthas-demo.md b/tutorials/katacoda/case-http-api-en/arthas-demo.md
new file mode 100644
index 000000000..7ba2cf1fa
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/arthas-demo.md
@@ -0,0 +1,11 @@
+
+
+
+
+Download `arthas-demo.jar` and start with the `java -jar` command:
+
+`wget https://alibaba.github.io/arthas/arthas-demo.jar
+java -jar arthas-demo.jar`{{execute T1}}
+
+`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results.
+If the generated random number is negative, a error message will be printed.
diff --git a/tutorials/katacoda/case-http-api-en/classpath-java-app.md b/tutorials/katacoda/case-http-api-en/classpath-java-app.md
new file mode 100644
index 000000000..ea49c354b
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/classpath-java-app.md
@@ -0,0 +1,32 @@
+
+Get system properties of the Java application through Http api and
+extract the value of `java.class.path`.
+
+`json_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"exec",
+ "command":"sysprop"
+}')`{{execute T3}}
+
+* Extract value with `sed`:
+
+`class_path=$(echo $json_data | tr -d '\n' | sed 's/.*"java.class.path":"\([^"]*\).*/\1/')
+echo "classpath: $class_path"`{{execute T3}}
+
+* Extract value with `json_pp/awk`:
+
+`class_path=$(echo $json_data | tr -d '\n' | json_pp | grep java.class.path | awk -F'"' '{ print $4 }')
+echo "classpath: $class_path"`{{execute T3}}
+
+Output:
+
+```
+classpath: arthas-demo.jar
+```
+
+NOTE:
+
+* `echo $json_data | tr -d '\n'` : Delete line breaks (the value of
+ `line.separator`) to avoid affecting the processing of `sed`/`json_pp`
+ commands.
+* `awk -F'"' '{ print $4 }'` : Use double quote as delimiter
diff --git a/tutorials/katacoda/case-http-api-en/finish.md b/tutorials/katacoda/case-http-api-en/finish.md
new file mode 100644
index 000000000..6dee7bb5f
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/finish.md
@@ -0,0 +1,8 @@
+
+The `Http API Tutorial` demonstrates the usage of Http API. If you have more tips or questions, please feel free to ask in Issue.
+
+* Issues: https://github.com/alibaba/arthas/issues
+* Documentation: https://alibaba.github.io/arthas
+
+
+If you are using Arthas, please let us know. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111)
\ No newline at end of file
diff --git a/tutorials/katacoda/case-http-api-en/http-api.md b/tutorials/katacoda/case-http-api-en/http-api.md
new file mode 100644
index 000000000..76a76c32a
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/http-api.md
@@ -0,0 +1,79 @@
+
+### Overview
+
+Http API provides a RESTful-like interactive interface, and both
+requests and responses data in JSON format. Compared with
+Telnet/WebConsole's output unstructured text data, Http API can provide
+structured data and support more complex interactive functions, such as
+a series of diagnostic operations in specific application scenarios.
+
+
+#### Access address
+
+The Http API address is: `http://ip:port/api`, the request parameters
+must be submitted using `POST`. Such as POST
+`http://127.0.0.1:8563/api`.
+
+Note: The telnet port `3658` has compatibility issues with the Chrome
+browser. It is recommended to use the http port `8563` to access the
+http api.
+
+
+#### Request data format
+
+```json
+{
+ "action": "exec",
+ "requestId": "req112",
+ "sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb",
+ "consumerId": "955dbd1325334a84972b0f3ac19de4f7_2",
+ "command": "version",
+ "execTimeout": "10000"
+}
+```
+Request data format description:
+
+* `action` : The requested action/behavior, please refer to "Request
+ Actions" for optional values.
+* `requestId` : Optional request ID, generated by the client.
+* `sessionId` : Arthas session ID, one-time command does not need to
+ set the session ID.
+* `consumerId` : Arthas consumer ID, used for multi-person sharing
+ sessions.
+* `command` : Arthas command line
+* `execTimeout` : Timeout for executing commands (ms), default value is 30000.
+
+Note: Different actions use different parameters. Set the parameters
+according to the specific action.
+
+#### Request Actions
+
+Currently supported request actions are as follows:
+
+* `exec` : The command is executed synchronously, and the command
+ results is returned after the command execution end or interrupted.
+* `async_exec` : The command is executed asynchronously, and the
+ scheduling result of the command is returned immediately. The command
+ execution result is obtained through `pull_results` action.
+* `interrupt_job` : To interrupt the foreground command of the session,
+ similar to the function of Telnet `Ctrl + c`.
+* `pull_results` : Get the result of the command executed
+ asynchronously, and execute it repeatedly in http long-polling mode.
+* `init_session` : Create new session.
+* `join_session` : Join the session, used to support multiple people
+ sharing the same Arthas session.
+* `close_session` : Close the session.
+
+#### Response status
+
+The state attribute in the response indicates the request processing
+state, and its value is as follows:
+
+* `SCHEDULED`: When the command is executed asynchronously, it means that
+ the job has been created, and may not be executed yet or is being
+ executed;
+* `SUCCEEDED`: The request is processed successfully (completed status);
+* `FAILED`: Request processing failed (completed status), usually
+ accompanied by a message explaining the reason;
+* `REFUSED`: The request is rejected (completed status), usually
+ accompanied by a message explaining the reason;
diff --git a/tutorials/katacoda/case-http-api-en/index.json b/tutorials/katacoda/case-http-api-en/index.json
new file mode 100644
index 000000000..9474d3422
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/index.json
@@ -0,0 +1,62 @@
+{
+ "title": "Arthas Case Http API",
+ "description": "Arthas Case Http API",
+ "difficulty": "master",
+ "time": "10-20 minutes",
+ "details": {
+ "steps": [
+ {
+ "title": "Arthas demo",
+ "text": "arthas-demo.md"
+ },
+ {
+ "title": "Start arthas-boot",
+ "text": "arthas-boot.md"
+ },
+ {
+ "title": "Http API",
+ "text": "http-api.md"
+ },
+ {
+ "title": "One-time command",
+ "text": "one-time-command.md"
+ },
+ {
+ "title": "Session Interaction",
+ "text": "session-interaction.md"
+ },
+ {
+ "title": "Web UI",
+ "text": "web-ui.md"
+ },
+ {
+ "title": "Make watch command output a map object",
+ "text": "watch-output-map.md"
+ },
+ {
+ "title": "Get classpath of Java application",
+ "text": "classpath-java-app.md"
+ }
+ ],
+ "intro": {
+ "text": "intro.md"
+ },
+ "finish": {
+ "text": "finish.md"
+ }
+ },
+ "environment": {
+ "uilayout": "terminal",
+ "showdashboard": true,
+ "dashboards": [
+ {
+ "name": "Web Port 8563",
+ "port": 8563
+ }
+ ]
+ },
+ "backend": {
+ "imageid": "java",
+ "environmentsprotocol": "http"
+ }
+}
\ No newline at end of file
diff --git a/tutorials/katacoda/case-http-api-en/intro.md b/tutorials/katacoda/case-http-api-en/intro.md
new file mode 100644
index 000000000..1f87fff4b
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/intro.md
@@ -0,0 +1,40 @@
+
+
+
+
+
+`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers.
+
+`Arthas` supports JDK 6+, supports Linux/Mac/Windows.
+
+## Background
+
+Oftentimes the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. What’s even worse, debugging in production environment is unacceptable, as it will suspend all the threads, leading to services downtime.
+
+Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be reproduced easily in a different environment, or even disappear once restarted.
+
+And if you’re thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle: test, staging, and then to production. Time is money! This approach is inefficient! Worse still, the issue may not be fixed since it might be irreproducible once the JVM is restarted, as described above.
+
+Arthas is built to solve these issues. A developer can troubleshoot production issues on the fly. No JVM restart, no additional code changes. Arthas works as an observer, that is, it will never suspend your running threads.
+
+## Key features
+
+- Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts)
+- Decompile a class to ensure the code is running as expected.
+- Check classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc.
+- Check the method invocation details, e.g. method parameter, returned values, exceptions and etc.
+- Check the stack trace of specified method invocation. This is useful when a developer wants to know the caller of the method.
+- Trace the method invocation to find slow sub-invocations.
+- Monitor method invocation statistics, e.g. QPS (Query Per Second), RT (Return Time), success rate and etc.
+- Monitor system metrics, thread states and CPU usage, GC statistics and etc.
+- Supports command line interactive mode, with auto-complete feature enabled.
+- Supports telnet and WebSocket, which enables both local and remote diagnostics with command line and browsers.
+- Supports profiler/Flame Graph
+- Supports JDK 6+
+- Supports Linux/Mac/Windows
+
+This tutorial takes a simple application as an example to demonstrate the the usage of Http API.
+
+* Github: https://github.com/alibaba/arthas
+* Docs: https://alibaba.github.io/arthas/
+
diff --git a/tutorials/katacoda/case-http-api-en/one-time-command.md b/tutorials/katacoda/case-http-api-en/one-time-command.md
new file mode 100644
index 000000000..6bc3de78b
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/one-time-command.md
@@ -0,0 +1,97 @@
+
+Similar to executing batch commands, the one-time commands are executed
+synchronously. No need to create a session, no need to set the
+`sessionId` option.
+
+```json
+{
+ "action": "exec",
+ "command": ""
+}
+```
+
+For example, get the Arthas version number:
+
+`curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"exec",
+ "command":"version"
+}
+' | json_pp`{{execute T3}}
+
+The response is as follows:
+
+```json
+{
+ "state" : "SUCCEEDED",
+ "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869",
+ "body" : {
+ "results" : [
+ {
+ "type" : "version",
+ "version" : "3.3.7",
+ "jobId" : 5
+ },
+ {
+ "jobId" : 5,
+ "statusCode" : 0,
+ "type" : "status"
+ }
+ ],
+ "timeExpired" : false,
+ "command" : "version",
+ "jobStatus" : "TERMINATED",
+ "jobId" : 5
+ }
+}
+```
+Response data format description:
+
+* `state`: Request processing status, refer to the description of
+ "Response Status".
+* `sessionId `: Arthas session ID, one-time command to automatically
+ create and destroy temporary sessions.
+* `body.jobId`: The job ID of the command, all output results of the
+ same job are the same jobId.
+* `body.jobStatus`: The job status of the command.
+* `body.timeExpired`: Whether the job execution timed out.
+* `body/results`: Command execution results.
+
+**Command result format description**
+
+```json
+ [{
+ "type" : "version",
+ "version" : "3.3.7",
+ "jobId" : 5
+ },
+ {
+ "jobId" : 5,
+ "statusCode" : 0,
+ "type" : "status"
+ }]
+```
+
+* `type` : The command result type, except for the special ones such as
+ `status`, the others remain the same as the Arthas command name.
+ Please refer to the section
+ "Special command results".
+* `jobId` : The job ID of the command.
+* Other fields are the data of each different command.
+
+Note: You can also use a one-time command to execute continuous output
+commands such as watch/trace, but you can't interrupt the command
+execution, and there may be hang up for a long time. Please refer to the
+example in the
+"Make watch command output a map object"
+section.
+
+Please try to deal with it in the following way:
+
+* Set a reasonable `execTimeout` to forcibly interrupt the command
+ execution after the timeout period is reached to avoid a long hang.
+* Use the `-n` parameter to specify a smaller number of executions.
+* Ensure the methods of the command matched can be successfully hit and
+ the `condition-express` is written correctly. If the `watch/trace` does
+ not hit, even if `-n 1` is specified, it will hang and wait until the
+ execution timeout.
diff --git a/tutorials/katacoda/case-http-api-en/session-interaction.md b/tutorials/katacoda/case-http-api-en/session-interaction.md
new file mode 100644
index 000000000..fe0eb2ea0
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/session-interaction.md
@@ -0,0 +1,321 @@
+
+Users create and manage Arthas sessions, which are suitable for complex
+interactive processes. The access process is as follows:
+
+* Create a session
+* Join the session (optional)
+* Pull command results
+* Execute a series of commands
+* Interrupt command execution
+* Close the session
+
+#### Create session
+
+Create session and save output into bash environment.
+
+`session_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"init_session"
+}
+')
+echo $session_data | json_pp`{{execute T3}}
+
+Note: The `json_pp` tool formats the output content as pretty json.
+
+Response result:
+
+```json
+{
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1",
+ "state" : "SUCCEEDED"
+}
+```
+
+extract session ID and consumer ID.
+
+The new session ID is:
+
+`session_id=$(echo $session_data | sed 's/.*"sessionId":"\([^"]*\)".*/\1/g')
+echo $session_id`{{execute T3}}
+
+`b09f1353-202c-407b-af24-701b744f971e`;
+
+consumer ID is:
+
+`consumer_id=$(echo $session_data | sed 's/.*"consumerId":"\([^"]*\)".*/\1/g')
+echo $consumer_id`{{execute T3}}
+
+`5ae4e5fbab8b4e529ac404f260d4e2d1_1`.
+
+#### Join session
+
+Specify the session ID to join, and the server will assign a new
+consumer ID. Multiple consumers can receive the same command results of
+target session. This interface is used to support multiple people
+sharing the same session or refreshing the page to retrieve the session
+history.
+
+Join session and save output into bash environment.
+
+`session_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"join_session",
+ "sessionId" : "'"$session_id"'"
+}
+')
+echo $session_data | json_pp`{{execute T3}}
+
+Response result:
+
+```json
+{
+ "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "state" : "SUCCEEDED"
+}
+```
+
+extract new consumer ID.
+
+The new consumer ID is
+
+`consumer_id=$(echo $session_data | sed 's/.*"consumerId":"\([^"]*\)".*/\1/g')
+echo $consumer_id`{{execute T3}}
+
+`8f7f6ad7bc2d4cb5aa57a530927a95cc_2 ` .
+
+#### Pull command results
+
+The action of pulling the command result message is `pull_results`.
+Please use the Http long-polling method to periodically pull the result
+messages. The consumer's timeout period is 5 minutes. After the timeout,
+you need to call `join_session` to allocate a new consumer.
+
+Each consumer is allocated a cache queue separately, and the pull order
+does not affect the content received by the consumer.
+
+
+The request parameters require session ID and consumer ID:
+
+`curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"pull_results",
+ "sessionId" : "'"$session_id"'",
+ "consumerId" : "'"$consumer_id"'"
+}
+' | json_pp`{{execute T3}}
+
+Use Bash scripts to regularly pull results messages:
+
+`while true; do curl -Ss -XPOST http://localhost:8563/api -d '
+{
+ "action":"pull_results",
+ "sessionId" : "'"$session_id"'",
+ "consumerId" : "'"$consumer_id"'"
+}
+' | json_pp; sleep 2; done`{{execute T4}}
+
+The response content is as follows:
+
+```json
+{
+ "body" : {
+ "results" : [
+ {
+ "inputStatus" : "DISABLED",
+ "jobId" : 0,
+ "type" : "input_status"
+ },
+ {
+ "type" : "message",
+ "jobId" : 0,
+ "message" : "Welcome to arthas!"
+ },
+ {
+ "tutorials" : "https://arthas.aliyun.com/doc/arthas-tutorials.html",
+ "time" : "2020-08-06 15:56:43",
+ "type" : "welcome",
+ "jobId" : 0,
+ "pid" : "7909",
+ "wiki" : "https://arthas.aliyun.com/doc",
+ "version" : "3.3.7"
+ },
+ {
+ "inputStatus" : "ALLOW_INPUT",
+ "type" : "input_status",
+ "jobId" : 0
+ }
+ ]
+ },
+ "sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
+ "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
+ "state" : "SUCCEEDED"
+}
+
+```
+
+
+#### Execute commands asynchronously
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"async_exec",
+ "command":"watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" ",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+Response of `async_exec`:
+
+```json
+{
+ "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
+ "state" : "SCHEDULED",
+ "body" : {
+ "jobStatus" : "READY",
+ "jobId" : 3,
+ "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
+ }
+}
+```
+
+* `state` : The status of `SCHEDULED` means that the command has been
+ parsed and generated the job, but the execution has not started.
+* `body.jobId` : The job id of command execution, filter the command
+ results output in `pull_results` according to this job ID.
+* `body.jobStatus` : The job status `READY` means that execution has not started.
+
+Switch to the shell output of the script that continuously pulls the result message (Terminal 4):
+
+```json
+{
+ "body" : {
+ "results" : [
+ {
+ "type" : "command",
+ "jobId" : 3,
+ "state" : "SCHEDULED",
+ "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
+ },
+ {
+ "inputStatus" : "ALLOW_INTERRUPT",
+ "jobId" : 0,
+ "type" : "input_status"
+ },
+ {
+ "success" : true,
+ "jobId" : 3,
+ "effect" : {
+ "listenerId" : 3,
+ "cost" : 24,
+ "classCount" : 1,
+ "methodCount" : 1
+ },
+ "type" : "enhancer"
+ },
+ {
+ "sizeLimit" : 10485760,
+ "expand" : 1,
+ "jobId" : 3,
+ "type" : "watch",
+ "cost" : 0.071499,
+ "ts" : 1596703453237,
+ "value" : [
+ [
+ -170365
+ ],
+ null,
+ {
+ "stackTrace" : [
+ {
+ "className" : "demo.MathGame",
+ "classLoaderName" : "app",
+ "methodName" : "primeFactors",
+ "nativeMethod" : false,
+ "lineNumber" : 46,
+ "fileName" : "MathGame.java"
+ },
+ ...
+ ],
+ "localizedMessage" : "number is: -170365, need >= 2",
+ "@type" : "java.lang.IllegalArgumentException",
+ "message" : "number is: -170365, need >= 2"
+ }
+ ]
+ },
+ {
+ "type" : "watch",
+ "cost" : 0.033375,
+ "jobId" : 3,
+ "ts" : 1596703454241,
+ "value" : [
+ [
+ 1
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 13,
+ 491
+ ],
+ null
+ ],
+ "sizeLimit" : 10485760,
+ "expand" : 1
+ }
+ ]
+ },
+ "consumerId" : "8ecb9cb7c7804d5d92e258b23d5245cc_1",
+ "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
+ "state" : "SUCCEEDED"
+}
+```
+
+
+The `value` of the watch command result is the value of watch-experss,
+and the above command is `{params, returnObj, throwExp}`, so the value
+of the watch result is an array of length 3, and each element
+corresponds to the expression in the corresponding order.
+
+Please refer to the section "Make watch command output a map object".
+
+#### Interrupt command execution
+
+Interrupt the running foreground job of the session:
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"interrupt_job",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+```json
+{
+ "state" : "SUCCEEDED",
+ "body" : {
+ "jobStatus" : "TERMINATED",
+ "jobId" : 3
+ }
+}
+```
+
+#### Close session
+
+Specify the session ID to close the session.
+
+`curl -Ss -XPOST http://localhost:8563/api -d '''
+{
+ "action":"close_session",
+ "sessionId" : "'"$session_id"'"
+}
+''' | json_pp`{{execute T3}}
+
+```json
+{
+ "state" : "SUCCEEDED"
+}
+```
\ No newline at end of file
diff --git a/tutorials/katacoda/case-http-api-en/watch-output-map.md b/tutorials/katacoda/case-http-api-en/watch-output-map.md
new file mode 100644
index 000000000..53e7b42e6
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/watch-output-map.md
@@ -0,0 +1,92 @@
+
+The result value of `watch` is generated by calculating the
+`watch-express` ognl expression. You can change the ognl expression to
+generate the desired value, please refer to
+[OGNL document](https://commons.apache.org/proper/commons-ognl/language-guide.html).
+
+> Maps can also be created using a special syntax.
+>
+>#{ "foo" : "foo value", "bar" : "bar value" }
+>
+>This creates a Map initialized with mappings for "foo" and "bar".
+
+The following command generates values in map format:
+
+```bash
+watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5
+```
+
+Execute the above command in Telnet shell/WebConsole, the output result:
+
+```bash
+ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[
+ @String[params]:@Object[][
+ @Integer[1],
+ ],
+ @String[returnObj]:@ArrayList[
+ @Integer[2],
+ @Integer[241],
+ @Integer[379],
+ ],
+ @String[throwExp]:null,
+]
+```
+
+Execute the above command with Http api, pay attention to escaping the JSON double quotes:
+
+`
+curl -Ss -XPOST http://localhost:8563/api -d @- << EOF
+{
+ "action":"exec",
+ "execTimeout": 30000,
+ "command":"watch *MathGame prime* '#{ \"params\" : params, \"returnObj\" : returnObj, \"throwExp\": throwExp}' -n 3 "
+}
+EOF`{{execute T3}}
+
+Http api execution result:
+
+```json
+{
+ "body": {
+ ...
+ "results": [
+ ...
+ {
+ ...
+ "type": "watch",
+ "value": {
+ "params": [
+ 1
+ ],
+ "returnObj": [
+ 2,
+ 5,
+ 17,
+ 23,
+ 23
+ ]
+ }
+ },
+ {
+ ...
+ "type": "watch",
+ "value": {
+ "params": [
+ -98278
+ ],
+ "throwExp": {
+ "@type": "java.lang.IllegalArgumentException",
+ "localizedMessage": "number is: -98278, need >= 2",
+ "message": "number is: -98278, need >= 2",
+ "stackTrace": [
+ ...
+ ]
+ }
+ }
+ },
+ ...
+}
+```
+
+You can see that the value of the watch result becomes a map object, and
+the program can read value through a key .
diff --git a/tutorials/katacoda/case-http-api-en/web-ui.md b/tutorials/katacoda/case-http-api-en/web-ui.md
new file mode 100644
index 000000000..dac96fbc1
--- /dev/null
+++ b/tutorials/katacoda/case-http-api-en/web-ui.md
@@ -0,0 +1,23 @@
+
+
+
+A Web UI based on Http API, visit url :
+https://[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com/ui .
+
+Completed functions:
+
+* Create a session
+* Copy and open the url to join the session, share the session with
+ multiple people
+* Continuously pull session command result messages
+* Refresh the web page or join the session to pull command messages
+ history
+* Control input or interrupt command status
+
+
+Pending function:
+
+* Improve the readability of command result messages
+* Support automatic completion of input commands and command templates
+* Provide command help
+* Support personal profile settings