Plantumlをサーバーレスで実行をやってみた


人様のつくったものを実行した＋アルファの試行錯誤メモ

## これを使わせてもらう

https://github.com/mmajis/plantuml-serverless

実行するとこけたので、逐次なんとかする

## 設定

http://kubotti.hatenablog.com/entry/2017/01/12/150735





## 依存ライブラリ

### serverless-domain-manager

https://www.npmjs.com/package/serverless-domain-manager
https://qiita.com/ooharabucyou/items/039b57474820ee9d803e
https://qiita.com/imura81gt/items/5cf490468f95ce3d100b

enabled: falseにすると無効化できるのね。
profileも指定できると。。

### html-minifier

https://github.com/kangax/html-minifier
https://hail2u.net/blog/bye-html-minifier.html

globalにいれたらエラーが消えた

### serverless導入

https://qiita.com/seiya_orz/items/fc6bbb3ef99ef6190ca6




## 導入できたっぽいけど結果

うまく画像ができない
リージョンを東京にしたせいか、、
エラーが出たせいか、、
どうもレスポンスのlengthが3/2くらい長いので、文字コードが関係していそう？？

### 更新箇所

s3
cloudformation
gateway
lambda

### 導入できたっぽいけど、まだ若干怪しい

```
  Serverless Error ---------------------------------------

  Too Many Requests

  Stack Trace --------------------------------------------

ServerlessError: Too Many Requests
    at BbPromise.fromCallback.catch.err (/usr/local/lib/node_modules/serverless/lib/plugins/aws/provider/awsProvider.js:262:11)
```

```
Serverless: Recoverable error occured (write EPROTO 140735959655360:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:659:
), sleeping 5 seconds
```

### 削除するか

```
SLS_DEBUG=* sls remove
```

途中でエラーが出てbucketがなくなってうまく削除できないまま。。
ひどい。。





## 四苦八苦

### いまさらフレームワークのコマンドを確認

Serverless Framework Commands - AWS Lambda - Deploy
https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/


### エラー

権限不足だったので付与した

Serverlessのデプロイ時に"The specified bucket does not exist"って言われた時の対処 - Qiita
https://qiita.com/honmaaax/items/3f21064c5973a2594358


### 文字化けしてたみたいでレスポンスが空っぽの画像

文字コード json.getBytes - Google 検索
https://www.google.co.jp/search?num=100&safe=off&ei=nOPyWtfiMpfI8wXJr4GoAw&q=%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89+json.getBytes+&oq=%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89+json.getBytes+&gs_l=psy-ab.3...25443.29602.0.29951.11.10.0.0.0.0.242.1246.0j5j2.7.0....0...1.1j4.64.psy-ab..7.0.0....0.WXDYUWKV2sM

https://qiita.com/inabajunmr/items/e49408ab356b6a63ea91

```
def lambda_handler(event, context):

    # binary_dataを用意(省略）
    binary_data = xxxxx

    response = {
       "statusCode": 200,
       "headers":{
           "Content-Type": "image/jpeg",
       },
       "isBase64Encoded": True,
        "body" : base64.b64encode(binary_data).decode('utf-8')
       }
    return response
```


eu-west-1がデフォルトリージョンで、そこだと画像が帰ってくるのに、us,apはダメだった。
最後のレスポンス前のgetBytesにutf-8を指定でうまくいった。
全部のgetBytesに指定した方がいいのかな。


### mvn

cleanしなくてもいいのか迷った	

`mvn package`で何度もビルドすると置き換わらないファイルが出たりする - Qiita
https://qiita.com/fukasawah/items/5771a4bfad27e497c2e0


### SVGなら日本語フォントなくても可能

PlantUML | プログラマーズ雑記帳
http://yohshiy.blog.fc2.com/blog-category-22.html

> ただし、 SVG で出力する場合にはフォントの設定に関係なく日本語も OK です。

一旦、SVGにすっか。

### 日本語が豆腐に文字化けするのでフォントを変える方法

Atom+PlantUMLで見た目もいい感じのシーケンス図を作成する - Qiita
https://qiita.com/k_nakayama/items/77ca73753ebd049a66de


### コマンドでのフォント指定

SphinxでPlantUMLを使う時のデフォルト・フォントが指定できました - chofutaroメモ
http://d.hatena.ne.jp/chofutaro/20141109/1415530844

### lambdaにフォント

面倒だから今回はパス

Lambdaの実行環境にフォントを追加する - Qiita
https://qiita.com/komeda-shinji/items/e049edd1389579059c53

AWS LambdaでPhantomJS日本語フォント対応 | RCO Ad-Tech Lab Blog
https://www.rco.recruit.co.jp/career/engineer/blog/34/

AWS Lambda 日本語フォント - syonbox
https://scrapbox.io/syon/AWS_Lambda_%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88

### サーバーレスのchromeとかできるのか。。

serverless-chrome で日本語を表示できるようにする - いけむランド
http://fd0.hatenablog.jp/entry/2017/09/10/223042



### 公式のdockerがあるのね

いまさら、サーバーレスじゃなくてもよかったかも。。まあサーバーレスに越したことはない。

plantuml server で日本語が豆腐になってしまったら | 日々どんまい
https://donmaidays.wordpress.com/2017/06/02/plantuml-server-%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%8C%E8%B1%86%E8%85%90%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9F%E3%82%89/

plantuml/plantuml-server: PlantUML Online Server
https://github.com/plantuml/plantuml-server


### 結果的に変更した箇所

```
diff --git a/serverless.yml b/serverless.yml
index 97aaab2..a92e8d3 100644
--- a/serverless.yml
+++ b/serverless.yml
@@ -5,9 +5,9 @@ frameworkVersion: ">=1.4.0 <2.0.0"
 provider:
   name: aws
   runtime: java8
-  region: eu-west-1
+  region: ap-northeast-1
   stage: dev
-  profile: core
+  profile: hogetarou
   cfLogs: true
   timeout: 30
   environment:
@@ -29,6 +29,7 @@ custom:
     basePath: ''
     stage: "${self:custom.stage}"
     createRoute53Record: true
+    enabled: false
   apigwBinary:
     types:
       - '*/*'
diff --git a/src/main/java/com/nitor/plantuml/lambda/LambdaBase.java b/src/main/java/com/nitor/plantuml/lambda/LambdaBase.java
index 241dbaf..d73ec1d 100644
--- a/src/main/java/com/nitor/plantuml/lambda/LambdaBase.java
+++ b/src/main/java/com/nitor/plantuml/lambda/LambdaBase.java
@@ -107,7 +107,7 @@ class LambdaBase {
   }
 
   void sendExceptionResponse(OutputStream outputStream, StatusCodeException statusCodeException) throws IOException {
-    String base64Response = Base64.getEncoder().encodeToString(statusCodeException.getMessage().getBytes());
+    String base64Response = Base64.getEncoder().encodeToString(statusCodeException.getMessage().getBytes("UTF-8"));
     sendJSONResponse(outputStream, base64Response, statusCodeException.getStatusCode());
   }
 
@@ -197,4 +197,4 @@ class LambdaBase {
   private void handleInputError(Exception e) {
     throw new IllegalArgumentException("Could not parse parameters", e);
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/nitor/plantuml/lambda/MapHandler.java b/src/main/java/com/nitor/plantuml/lambda/MapHandler.java
index 14a3968..e481fef 100644
--- a/src/main/java/com/nitor/plantuml/lambda/MapHandler.java
+++ b/src/main/java/com/nitor/plantuml/lambda/MapHandler.java
@@ -22,7 +22,7 @@ public class MapHandler extends LambdaBase implements RequestStreamHandler  {
     String encodedUml = getEncodedUml(event);
     try {
       String imageMap = plantUmlUtil.renderImageMap(encodedUml);
-      String base64Response = Base64.getEncoder().encodeToString(imageMap.getBytes());
+      String base64Response = Base64.getEncoder().encodeToString(imageMap.getBytes("UTF-8"));
       SyntaxCheckResult syntaxCheckResult = plantUmlUtil.checkSyntax(encodedUml);
       if (!syntaxCheckResult.isError()) {
         sendOKDiagramResponse(outputStream, base64Response, DiagramType.IMAGEMAP);
@@ -34,4 +34,4 @@ public class MapHandler extends LambdaBase implements RequestStreamHandler  {
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/nitor/plantuml/lambda/SyntaxHandler.java b/src/main/java/com/nitor/plantuml/lambda/SyntaxHandler.java
index 86c12b5..5b2fab2 100644
--- a/src/main/java/com/nitor/plantuml/lambda/SyntaxHandler.java
+++ b/src/main/java/com/nitor/plantuml/lambda/SyntaxHandler.java
@@ -26,7 +26,7 @@ public class SyntaxHandler extends LambdaBase implements RequestStreamHandler  {
       SyntaxCheckResult syntaxCheckResult = plantUmlUtil.checkSyntax(encodedUml);
       Gson gson = new GsonBuilder().create();
       String json = gson.toJson(syntaxCheckResult);
-      String base64Response = Base64.getEncoder().encodeToString(json.getBytes());
+      String base64Response = Base64.getEncoder().encodeToString(json.getBytes("UTF-8"));
       if (!syntaxCheckResult.isError()) {
         sendOKJSONResponse(outputStream, base64Response);
       } else {
@@ -37,4 +37,4 @@ public class SyntaxHandler extends LambdaBase implements RequestStreamHandler  {
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/ui/index.html b/ui/index.html
index a287f78..b02a052 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -1803,7 +1803,7 @@
           if (u1!=null) return;
           var u2 = $(this).attr("uml");
           if (u2=="") return;
-          $(this).attr("src", "png/"+encode64(e.data));
+          $(this).attr("src", "svg/"+encode64(e.data));
           $(this).attr("uml", "");
           done = 1;
         });
```