OmniAICreator/Qiita-1.07M huggingface dataset:
テンプレートリテラルを本当にテンプレートエンジンっぽく使うサンプル

### テンプレートリテラルなるものがある

Perl、PHP、Rubyに代表されるスクリプト言語に比べると、初期のJavaSciptは以下の機能がなかったのが辛かった。

- ヒアドキュメント
- 変数展開

ES2015 / ES6 になってからは、テンプレートリテラルという構文ができたので、もう大丈夫。



### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/e4d16ad7-71f6-6881-758f-ad8883e263f0.png)

### ソースコード
```teml.html
<html>

<script type="text/javascript">

// 静的なサンプル
function tab1(){
return  `
    <table border=1>
    <tr>
    <td>ああ</td>
    </tr>
    </table>
 `;
}

// 文字列変数を展開する
function tab2(mes){
return  `
    <table border=1>
    <tr>
    <td>${mes}</td>
    </tr>
    </table>
 `;
}

//配列変数の中でメソッドを使ってみる（配列を文字列に）
function tab3(ary){
return  `
    <table border=1>
    <tr>
    <td>${ary.join('|')}</td>
    </tr>
    </table>
 `;
}

//変数展開の中のメソッドの中で変数展開をする
function tab4(ary){
return `
    <table border=1>
    <tr>
    ${
    ary.map( item => `<td>${item}</td>`).join('')
    }
    </tr>
    </table>
 `;
}
</script>

<div id="main"></div>

<script type="text/javascript">
let ele = document.querySelector("#main");
ele.insertAdjacentHTML('beforeend',tab1());
ele.insertAdjacentHTML('beforeend',tab2('hello'));
ele.insertAdjacentHTML('beforeend',tab3(['a','b','c']));
ele.insertAdjacentHTML('beforeend',tab4(['a','b','c']));
</script>
</html>

```

### こころ残り

HTMLテンプレートとして使うなら、htmlエスケープもしたいところ。

- h()という関数を作って都度エスケープする（←ダサい。忘れそう）
- ${}自体を上書きしちゃう（← 変数の中にhtmlタグが登場することもある）
- テンプレートに渡す前の変数や配列やハッシュの値を全部エスケープする
- コメントで  htsign さんからいただいた「テンプレートリテラルに関数をかませる」（← 読みやすい）
Microsoft Learn 6日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/6 は
**Core Cloud Services - Azure の概要**
 - 演習 - Azure でホストされる Web サイトを作成する
 - 演習 - App Service を構成する
 - 演習 - Azure Cloud Shell を使用して App Service にアクセスする

を受講。以下、簡易メモ。

# Core Cloud Services - Azure の概要
## 演習 - Azure でホストされる Web サイトを作成する
### App Service とは
インフラストラクチャを管理することなく、さまざまな種類の Web ベースのソリューションを構築およびホストできるようにする HTTP ベースのサービス。

### Microsoft Azure Marketplace とは
Azure で実行するために認定および最適化されたアプリケーションをホストするオンライン ストア。

あとは 演習項目なので割愛。
演習項目は、Azure にある WordPress のサービスを使ってブログを作ってみよう！というものでした。
Microsoft Learn 5日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/5 は
**Core Cloud Services - Azure の概要**
 - Azure とは
 - Azure サービスのツアー

を受講。以下、簡易メモ。

# Core Cloud Services - Azure の概要
## Azure とは
Microsoft が提供するクラウドコンピューティングプラットフォーム。
大規模グローバルネットワーク上でアプリケーションを自由にビルド、管理、デプロイできる。

### Azure でできること
現在、100を超えるサービスが提供されている。
視覚、聴覚、音声を使用してユーザーと自然にコミュニケーションできる AI および機械学習サービス
膨大な量のデータに対応するために動的に拡張されるストレージソリューション
なども提供されている。

## Azure サービスのツアー
### Azure サービス
サービスの全体像はこちら。(画像は Microsoft Learn より拝借)
![3-azure-services.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141029/2492b9ca-747e-6493-150e-fdf7c3f92c34.png)

一般的によく使用されているカテゴリが以下。各カテゴリのサービスは一部のみ掲載。
### コンピューティング
Azure では、アプリケーションとサービスをホストするためのさまざまなオプションが用意されている。
Azure Virtual Machines：Azure でホストされる Windows または Linux (VM)
Azure Kubernetes Service：コンテナー化されたサービスを実行する VM のクラスターを管理
Azure Functions：イベント ドリブンのサーバーレス コンピューティング サービス

### ネットワーク
コンピューティングリソースをリンクし、アプリケーションへのアクセスを提供する機能。
Azure Virtual Network：VPN 接続に VM を接続
Azure Load Balancer：受信および送信接続を複数のアプリケーションまたはサービスエンドポイントに分散
Azure Application Gateway：アプリケーションのセキュリティを高め、アプリサーバーファームの配信を最適化
Azure VPN Gateway：高パフォーマンスの VPN ゲートウェイを介して Azure Virtual Network にアクセス
Azure DNS：超高速の DNS 応答と非常に高いドメインの可用性を提供

### ストレージ
Azure Blob Storage：ビデオファイルやビットマップなどのオブジェクト用
Azure File Storage：ファイル サーバーのようにアクセスおよび管理可能なファイル共有
Azure Queue Storage：アプリケーション間のメッセージのキューおよび確実な配信のためのデータストア
Azure Table Storage：どんなスキーマからも独立した非構造化データをホストする NoSQL ストア

### モバイル
Azure を利用して、iOS、Android、Windows アプリ向けのモバイルバックエンドサービスを短期間で簡単に作成できる。
オフラインデータ同期、オンプレミスデータへの接続、プッシュ通知のブロードキャスト、ビジネス ニーズに合わせた自動スケーリングなども可能。

### データベース
さまざまなデータの種類とボリュームを格納するために複数のデータベースサービスが提供されている。
Azure Cosmos DB：NoSQL オプションをサポートするグローバル分散データベース
Azure SQL Database：自動スケーリング、統合インテリジェンス、堅牢なセキュリティを備えた、フルマネージドのリレーショナルデータベース

### Web
Web アプリと HTTP ベースの Web サービスを構築し、ホストするための最上級のサポートが含まれている。
Azure App Service：高性能のクラウドベース Web アプリを簡単に作成
Azure API Management：API を開発者、パートナー、従業員に安全かつ大規模に公開

### IoT
IoT Central：IoT 資産の接続、監視、管理を簡単かつ大規模に行えるフルマネージドグローバル SaaS ソリューション
Azure IoT Hub：複数の IoT デバイス間で安全な通信と監視を提供するメッセージングハブ

### ビッグ データ
Azure SQL Data Warehouse：超並列処理を活用してペタバイト単位のデータに対して複雑なクエリを短時間で実行するクラウドベースのエンタープライズデータウェアハウスを利用し、大規模な分析を実行
Azure HDInsight：クラウドの Hadoop クラスターからなる管理対象クラスターで大量のデータを処理
Azure Databricks:Azure でのその他の Big Data サービスを統合するコラボレーション対応の Apache Spark ベースの分析サービス

### 人工知能
Azure Machine Learning サービス：機械学習モデルの開発、トレーニング、テスト、デプロイ、管理、追跡に使用できるクラウドベースの環境
Azure Machine Learning Studio：共同作業に対応するドラッグアンドドロップ式の視覚的なワークスペース

### DevOps
Azure DevOps：高性能なパイプライン、無料のプライベート Git リポジトリ、設定可能なかんばんボード、広範囲で自動化されたクラウドベースのロード テストなど、コラボレーション用の開発ツールが提供
Microsoft Learn 4日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/4 は
**クラウドの概念 - クラウドコンピューティングの原則**
 - クラウドサービスの種類

を受講。以下、簡易メモ。

# クラウドの概念 - クラウドコンピューティングの原則
## クラウドサービスの種類
クラウドコンピューティングに関しては 3 つの主要なカテゴリがある。
### Iaas
サービスとしてのインフラストラクチャ。
以下のシナリオで使われる。
・ワークロードの移行
・テストと開発
・ストレージ、バックアップ、回復
#### コストと所有権
初期費用：なし
ユーザーの所有権：独自のソフトウェア、オペレーティング システム、ミドルウェア、およびアプリケーションに関する購入、インストール、構成、および管理に対する責任
プロバイダーの所有権：クラウド インフラストラクチャ (仮想マシン、ストレージ、ネットワークなど) を利用できることを保証する責任

### Paas
サービスとしてのプラットフォーム。
以下のシナリオで使われる。
・開発フレームワーク
・アナリティクス
#### コストと所有権
初期費用：なし
ユーザーの所有権：独自のアプリケーションの開発に対する責任
プロバイダーの所有権：オペレーティング システムの管理、ネットワーク、およびサービスの構成に対する責任

### Saas
サービスとしてのソフトウェア。
#### コストと所有権
初期費用：なし
ユーザーの所有権：アプリケーション ソフトウェアを使用するだけ。ソフトウェアのメンテナンスや管理を行う責任はなし。
プロバイダーの所有権：アプリケーション ソフトウェアのプロビジョニング、管理、およびメンテナンスに対して責任

比較。(画像は Microsoft Learn より拝借)
![5-layer-diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141029/1ae4ce79-ef99-5fd5-dc49-2b25c8d77099.png)
Microsoft Learn 3日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/3 は
**クラウドの概念 - クラウド コンピューティングの原則**
 - 資本的支出 (CapEx) と運用費 (OpEx) の比較
 - クラウドデプロイモデル
 - 

を受講。以下、簡易メモ。

# クラウドの概念 - クラウド コンピューティングの原則
## 資本的支出 (CapEx) と運用費 (OpEx) の比較
2つの投資へのアプローチ
1.　資本的支出 (CapEx)
  ...物理的なインフラストラクチャなどの事前費用がかかり、一定期間にわたる税の請求からその費用が控除される。つまり、初期費用。時間の経過と共に価値が減少。

2.　運用費 (OpEx)
  ...現在サービスや製品に費やしている金額。同じ年の税の請求からこの費用が控除される。初期費用はなし。

### CapEx コンピューティングコスト
一般的なオンプレでかかるコスト。
・サーバー
・ストレージ
・ネットワーク
・バックアップ、アーカイブ
・組織の継続性
・リカバリー
・インフラ
・技術担当者

### OpEx クラウドコンピューティングコスト
クラウドでかかるコスト。
・ソフトウェア、カスタマイズした機能のリース
・スケーリングでの料金請求
・組織レベルでの料金請求

### CapEx のメリット
資本支出において、プロジェクトおよび予算期間の開始時に費用を計画する。
よってコストは固定となり、いくら支出するか正しい把握が必須。
プロジェクトの開始時に費用を予測する必要がある場合は、CapEx の方が向いてる。

### OpEx のメリット
設備に投資する必要がない分、必要な分だけインフラへ支払いが必要となる。
需要が変動する、需要が不明な場合は、OpEx の方が向いてる。


## クラウドデプロイモデル
3種類のデプロイモデルがある。
3種類の分類定義として、
・データが格納される場所
・顧客がデータとやり取りする方法
・顧客がデータを取得する方法
・アプリケーションが実行される場所
・インフラストラクチャの量
がある。

### パブリッククラウド
最も一般的なデプロイモデル。
Microsoft Azure はこれ。
#### 長所
・高いスケーラビリティ/アジリティ
・従量課金制
・ハードウェアメンテナンスや更新が不必要
・最小限の技術に関する知識で活用(←ほんまかこれｗ)

#### 短所
パブリッククラウドが当てはまらない例
・パブリッククラウドを使用することで満たせないセキュリティ要件がある場合
・パブリッククラウドを使用することで満たせない政策、法的要件がある場合
・レガシーアプリケーションの維持が必要な場合(←前職でクソ悩まされたヤツ！！！)

### プライベートクラウド
独自のデータセンターでクラウド環境を構築、組織のユーザーにコンピューティング リソースへのセルフサービス アクセスを提供する。
自分が提供するハードウェアとソフトウェアサービスの購入、保守管理は自己責任となる。
#### 長所
・任意のシナリオやレガシ アプリケーションを確実にサポートできる
・セキュリティを完全に制御できる(＝責任は全て自分)
・厳密なセキュリティ、コンプライアンス、または法的要件を満たすことができる

#### 短所
・初期費用があり、初期構築時とメンテナンス時にハードウェアを購入する必要性が出てくる
・アジリティを制限する機器を所有しなければならない…かも
・IT スキルと専門知識が超必須

### ハイブリッドクラウド
名前の通り、パブリッククラウドとプライベートクラウドの合いの子。
#### 長所
・古くなったハードウェアやオペレーティングシステムを使用しているシステムを実行させてアクセス可能にできる
・ローカル or クラウドどちらで実行するかを適切に選択できる
・セキュリティ、コンプライアンス要件を場合に応じて自前の機器で対応できる

#### 短所
・前払いの CapEx コストを一部含むため場合によっては高くつくこともある
・設定、管理が複雑になる場合も
不具合の再現手順を気軽に動画に残すにはパワポが手軽

[ソフトウェアテストの小ネタ Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/software-testing-koneta)２日目の記事です。

初日の方が100以上のいいねを集めていて非常にやりづらいですが、初志貫徹して、本当の小ネタを書きます。

ソフトウェアテストをしていると、不具合の再現手順をレポートする機会も多いですが、文字だけよりも画像あり、画像ありよりも動画ありのほうがわかりやすい場合もあります。

そんなとき、おそらくどの職場でも使えて一番手っ取り早い方法として「パワポで動画をとる」という手があります。

## やりかた

パワポを開いて、挿入タブの「メディア」にある「画面録画」を選択します。
（パワポのバージョンによって異なる可能性もあるので、探してみましょう）

![powerpoint_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/fcafc3a1-17ed-618d-79d7-0d6303e5e96e.png)

画面が薄く白くなって、上のほうにメニューが出てくるので、範囲選択をしましょう。
範囲選択すると赤い点線で録画対象範囲が囲われます。

![powerpoint_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/e5cd0097-abf8-c63e-5b06-24cbdcf04466.png)

ここまでできたら録画ボタンをクリック。
３秒のカウントダウンののち、録画が始まります。

操作が終わったら、Windowsキー＋Shiftキー＋Qで停止です。

録画を停止すると、パワポのスライドの上に動画が載っています。便利。

![powerpoint_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/9ebecec2-4977-da70-8e68-357323d15ac0.png)

この動画、パワポでしか再生できないなんてことは当然なく、右クリックから「メディアに名前を付けて保存」をすると、mp4の拡張子でエクスポートでき、あとはお好きなBTSなりにアップすればOK。

![powerpoint_4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/78864a6a-53b4-2f6e-2d22-8964b1ab1a45.png)

## サンプル

Qiitaにアップする都合で、Gifにしてありますが、こんな感じに違和感なく録画できます。

![パワポ動画.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/608c7085-bde4-fb92-f64a-04ae5302ec74.gif)



## 他の方法

Windows10を使っている人は標準の録画機能を使うとよいとおもいます。

参考：[Windows 10 の標準機能で画面のキャプチャと動画を録画する方法「スクリーンショット」 | パソブル](https://www.pasoble.jp/windows/10/screen-capture.html)

が、Windows7しか使えない環境の方とか、Windows10の標準の録画が使いづらい方とか、パワポでちょろっとやってみると楽だと思います。ぜひ。
Volto 4 alpha を試す方法



# Plone 独自インストール

## CORS

buildout の 

```
[instance]
recipe = plone.recipe.zope2instance
```

に以下を追記

```
zcml-additional =
  <configure xmlns="http://namespaces.zope.org/zope"
             xmlns:plone="http://namespaces.plone.org/plone">
  <plone:CORSPolicy
    allow_origin="http://localhost:3000,http://127.0.0.1:3000"
    allow_methods="DELETE,GET,OPTIONS,PATCH,POST,PUT"
    allow_credentials="true"
    expose_headers="Content-Length,X-My-Header"
    allow_headers="Accept,Authorization,Content-Type,X-Custom-Header,Origin"
    max_age="3600"
    />
  </configure>
```

buildoutの実行

```
$ ./bin/buildout
```

Ploneの起動

```
$ ./bin/instance fg
```

Ploneインスタンスを作る (id: `Plone` とする必要がある)

## plone.restapi

- インストールバージョン Version 5.0.2 以降
- アドオン(add-on) でplone.restapiで有効化

## Block編集

- Plone サイト設定
- Dexterityコンテンツタイプ
- Page
    - 振る舞い
        - Blocks(Enables Volto Blocks support) -- On


# Ploneを簡単に

Voltoに内蔵している、 `docker-compose.yml` を使うと、以下のイメージからセットアップが終わったPloneが提供される

```
kitconcept/plone.restapi:latest
```

# Volto

## NVM

lts/erbium (v12.13.0) をインストール

```
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
$ nvm install --lts  
```

## yarn

```
$ curl -o- -L https://yarnpkg.com/install.sh | bash
```

## create volto app
```
$ nvm use v12.13.0
$ npx @plone/create-volto-app@alpha my-volto-app
```

## 起動

```
$ cd my-volto-app
$ yarn start
```

## 確認

http://localhost:3000

にて、Voltoの画面が出てくる
Microsoft Learn 2日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録

12/2 は
**クラウドの概念 - クラウド コンピューティングの原則**
 - コンプライアンスの条件と要件
 - 規模の経済

を受講。以下、簡易メモ。

# クラウドの概念 - クラウド コンピューティングの原則
## コンプライアンスの条件と要件
### コンプライアンス認証
1. 刑事裁判情報サービス
2. クラウドセキュリティ アライアンス(CSA)の STAR 認定資格
3. 一般データ保護規則 (GDPR)
4. EU モデル条項
5. 医療保険の携行性と責任に関する法律 (HIPAA)
6. 国際標準化機構 (ISO) / 国際電気標準会議 (IEC) 27018
7. 多層クラウド セキュリティ (MTCS) シンガポール
8. Service Organization Controls (SOC)
9. National Institute of Standards and Technology (NIST)
10. 英国政府の G-Cloud

## 規模の経済
より大きな規模で運用しているときに、より効率的に操作したり、単位あたりのコストを減らしたりすることができる。
コスト上の利益は、クラウドコンピューティングでの重要な利点である。
AzureのOracle VM イメージから作ったVirtual MachineのOSディスクのサイズを増やす

# 経緯

AzureのOracle VM イメージから作ったVirtual Machineのディスク容量が足りなくなり、ディスクサイズを増やした際の方法です。

# 筆者の環境

* Azure Virtual Machines
* Oracle Linux Server release 7.4
* Oracle Database 12c Standard Edition Release 12.2.0.1.0

# Azureの設定

仮想マシンを停止後、Azure Portalの該当Virtual Machineの[ディスク]でOSディスクを選択し、[構成]で、所望のディスクサイズを設定します。

ここで設定したサイズによって、価格とパフォーマンス上限が決まります。一度設定すると、そのサイズより縮小することではできません。
https://azure.microsoft.com/ja-jp/pricing/details/managed-disks/

# Linuxの設定

現在のパーティションを確認します。ここでは、`/`にマウントされている、`/dev/sda2`のパーティションを拡張します。

```sh
$ sudo lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
fd0      2:0    1    4K  0 disk
sda      8:0    0   60G  0 disk
├─sda1   8:1    0  500M  0 part /boot
└─sda2   8:2    0 29.5G  0 part /
sdb      8:16   0    8G  0 disk
└─sdb1   8:17   0    8G  0 part /mnt/resource
```

`/dev/sda2`のパーティションをディスクいっぱいのサイズで作成し直します。

```sh
$ sudo fdisk /dev/sda

The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 is deleted

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (2-4, default 2): 2
First sector (1026048-125829119, default 1026048):
Using default value 1026048
Last sector, +sectors or +size{K,M,G} (1026048-125829119, default 125829119):
Using default value 125829119
Partition 2 of type Linux and of size 59.5 GiB is set

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
```

再起動します。

```
$ sudo shutdown -r now
```

ファイルシステムに反映します。

```
$ sudo btrfs filesystem resize max /
```

以上で、パーティション`/dev/sda2`のサイズが拡張されました。
Microsoft Learn 1日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録

12/1 は
**クラウドの概念 - クラウド コンピューティングの原則**
 - はじめに
 - クラウドコンピューティングとは
 - クラウドコンピューティングのメリット

を受講。以下、簡易メモ。

# クラウドの概念 - クラウド コンピューティングの原則
## クラウドコンピューティングとは
ストレージスペースや CPU などを他の会社から借りること
料金は使った分だけ払う、という仕組み

プロバイダーによって提供サービスは異なるが、だいたいは以下のサービスは含まれる。
　・コンピューティング能力
　・ストレージ
　・ネットワーク
　・分析

### コンピューティングの選択肢
1. VM (仮想マシン)
  ...デスクトップまたはラップトップのようなコンピューターのエミュレーション。オペレーティングシステムとハードウェアが含まれていて、ユーザーには、Windows(/Linux)が稼働している物理的なコンピューターのように表示されます。

2. コンテナ
  ...一貫性のある分離された実行環境がアプリケーションに提供される。VM と違い、ゲストオペレーティングシステムがないので、ユーザーはアプリを起動するだけ。

3. サーバレス
  ...サーバーの作成、構成、管理をせずにアプリケーションコードを実行することができる。

3つの違いは以下のようになっている(画像は Microsoft Learn より拝借)
![2-vm-vs-container-vs-serverless.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141029/780a4eda-f4fb-4ed7-cd3a-2d97a3bc4aa9.png)



## クラウドコンピューティングのメリット
### コスト効率に優れている
大半は、**従量課金制** もしくは **使用量ベース** の料金体系になっている。

### スケーラブル
任意のタイミングで使用しているリソースとサービスを増減できる。
1.　垂直スケーリング(スケールアップ)
  ...既存のサーバーの能力を高めるためにリソースを追加するプロセス

2.　水平スケーリング(スケールダウン)
  ...1つのユニットとして相互に機能するサーバーを追加するプロセス

### 弾力性に優れている
リソースの割り当て量を自動的に増やしてトラフィックの増加に対処できる。
トラフィックが正常値に戻ると、自動的に追加リソースを解除してコストを最小限に抑えることが可能。

### 最新の状態が維持される
クラウドを使用することによって、ソフトウェアの修正プログラムの維持、ハードウェアのセットアップ、アップグレード、およびその他の IT 管理タスクにかかる負担が減らせる。
また、プロバイダーによって、ハードウェアは維持およびアップグレードされるので、ハードウェアの更新プログラムを自動的に利用できる。

### 信頼性に優れている
プロバイダーでは、ご利用のデータが常に安全であることを保証するために、データのバックアップ、ディザスター リカバリー、データ レプリケーションのサービスを提供している。

### グローバル
冗長性と地域に対してサービスを複数のリージョンにレプリケートしたり、顧客に対してデータ所在地と準拠法を確実に満たすように、特定のリージョンを選択したりすることができる。

### セキュリティで保護
インフラストラクチャを脅威から守るための物理的なセキュリティとしては、プロバイダーは物理的資産を保護する目的で壁、カメラ、門、警備員などに多額投入している。 また、従業員がアクセスできるのは、確実に管理権限を与えられたリソースのみするための厳格な手順なども用意している。
マンガでわかる Builder

![3EBA1A79-5F92-40BC-A65A-031469A0C4CF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/a3105570-e204-0ced-1f91-0d421aad0daf.png)

Builder はちょうぜつ建築ロボなので、どんなに複雑な指令を出しても間違えないのがいいですね。カッコの閉じ忘れとかクオートのエスケープ漏れとか、人間なら疲れてやらかしてしまう失敗を絶対にしない。おかげで、遠慮なく複雑な構造物を作らせることができます。

丹精込めた職人の手作業には心がこもってるんだけど、それ単純作業でミスしないとかそんな非人間的な作業に能力発揮してもらうんじゃなくて、もっと意味のあることに使っていきましょう。産業革命はもう済んでるんだから、職人がやるのは手作業じゃなくて Builder ロボの操作じゃないと。(め「目グレップは脳の肉体労働だからな」)

SQL や HTML はただの文字列じゃないかって? プログラム言語にしか着目していない方は、ここよく間違われるんですよね。たくさんのオブジェクトを `new` して `set` するものが Builder の対象になる「複雑な構造物」なんじゃないかって (もちろんそういう複雑な構造物もありますよ)。

いえいえ、結果できるものが文字列だったとしても「文法を持った言語」とかなら、オブジェクトのネスト構造と同じ意味を持ちますよ。ほか、ゲームのグラフィックだって、言ってみればフレームバッファにあるただのバイト列ですが、リアルな画面の描写には、さまざまなジオメトリとテクスチャを使ったGPU演算で生成されるじゃないですか。シーンビルダーですね。そういうことですよ。

もうひとつ、このロボ、対象の構築に関する知識が過不足なく揃っているオブジェクトだってところがポイントです。ロボなので一式まるっと後継互換機と買い替えることができるし、同じメーカーのロボならだいたい操作マニュアルが同じなので、そういうふうになってると、すぐに使えて楽チンです。オブジェクト指向ですね。
プロジェクトを円滑にすすめるために今すぐできること

この記事は[PONOS Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ponos)の9日目の記事です。
- - -

##プロジェクトが円滑に進むと
当然ですが携わっている人がみんなハッピーになります。
気持ちよく設計したり、コーディングしたりできたほうが誰しもいいはずです。
なので現在の環境に入って気づいたプロジェクトが円滑に進むちょっとしたポイントを紹介したいと思います。

##仕様書をフレッシュな状態にして有効活用
どんなプロジェクトにも存在する仕様書ですが、とても重要なものです。
これをどれだけ活用できるかでプロジェクトの進行度合いが変わると言っても過言ではないでしょう。

- Lv1.仕様書が存在し、それを見れば既存の実装内容がわかる
- Lv2.仕様書が常に最新の状態に更新されており、その資料を頼りに実装をすることができる
- Lv3.実装者が仕様決めに参加していなくても仕様書を参考に実装をすることができる

Lv2までできていれば、そのプロジェクトは円滑に進むことが多いと思います。
Lv3の段階になると仕様書に記載する情報が多くなってしまい、作成する側も一苦労になってしますが、逆に仕様についての質問を最小限に抑えられるので<font color="red">コミュニケーションコストの低下</font>に繋がります。

※仕様書についての疑問点を話し合うことはもちろん重要です。

##コミュニケーションツールの活用
皆さんはコミュニケーション(ChatWorkやSlack)を使用していますか？
コミュニケーションツールと言ってもただの文字での会話だと思うかもしれませんが、それ以上の効果があります。


- <b>新規参画者の連絡手段導入がスムーズになる</b>

    <font color="black">コミュニケーションツールは特定のグループ間でやりとりを行うことを主としているため、新規参画者が増えてもグループに入ってきてもらうだけで即座に既存メンバーと連絡を取れるようになります。
これは既存の参画メンバーにとっても同じで、新規参画者側から自分たちのグループに入ってきてくれるので<font color="red">ノーコストで連絡手段をえることができます</font>。</font>

<br />

- <b>情報交流の円滑化</b>

    <font color="black">コミュニケーションツールはチャンネルを作成することができ、エンジニアやデザイナーなどといった業務用途ごとにわけて作成すると、<font color="red">互いの進捗が確認しやすく、また共通の課題や問題提起を行えるため非常に便利です</font>。
また、万が一宛先の人が中々反応しなかった場合、近くにいる仲間が「これ気づいてる？」と確認を促すこともできるのでプロジェクト内の<font color="red">うっかりを大幅に減らすことができます</font>。</font>

<br />

- <b>コミュニケーションの敷居を下げる</b>

    <font color="black">業務とは関係ない共通の趣味や話題を話せるチャンネルも用意するとさらにいいでしょう。
会社のグループを使ってなにをやっているんだと思う方もいるかもしれませんが、こういったチャンネルを用意することによって普段業務ではあまり関わり合いのない人がどういう人なのかを知ることができ、いざコミュニケーションが必要になったときにその敷居が下がります。もちろん、既存メンバー同士の交流にもなるため、社内の雰囲気が良くなるきっかけになると思います。
コミュニケーションコストも色々とありますが、相手がわからないから話しづらいという初対面では解決しづらい問題を事前に摘んでおけるのはプロジェクト全体でみても有用ではないでしょうか。
</font>

<br />

- <b>宛先の人が休暇をとっているかどうか分かる</b>

    <font color="black">業務内容を個人チャットではなく、用途ごとに分けた業務用チャットで行うことが前提とはなりますが、仮に宛先の人が本日休暇をとっておりそれに気づかずに送信してしまっても同チャンネルの知っている人が教えてくれます。
それにより次善策をとることができるようになるので知らなかった場合と比べて<font color="red">大幅な時間短縮</font>になるでしょう。</font>

ざっとあげただけでもこれだけの利点があり、ありがちなミスや手間を減らすことに一役かってくれることでしょう。
唯一の欠点があるとすれば導入時のコストですが、あらかじめ少し手間をかけておけば後々よくなるのは仕様書と同じだと思います。


##最後に
今回あげたのは進行中のプロジェクトでも比較的簡単に導入できる2つでしたが、これがあるとないとではやはりかなりの差があります。
どこまでいってもコミュニケーションコストというのは存在するので、利用できるものは利用してそれを最小限に抑えることが円滑なプロジェクト進行の支えになるのではないでしょうか。
Rails6 のちょい足しな新機能を試す109（while_preventing_writes 編)

# はじめに

Rails 6 に追加された新機能を試す第109段。 今回は、while_preventing_writes 編です。
Rails 6 では、 `while_preventing_writes` が追加されました。

multi-db 関連のメソッドで、 while_preventing_writes のブロック内では、 DBへの書き込みができません。
同じDBに対してDBのConnection を別に作成しても書き込みはできないようになっています。

Ruby 2.6.5, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.0
```

今回は、簡単なスクリプトを作って確認します。

# Rails プロジェクトを作成する

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# User モデルを作成する

`User` モデルを作成します。


```shell
$ bin/rails g model User name
```

# User モデルを編集する

User モデルのDBの Connection を `ActiveRecord::Base.connection` とは別になるように変更します。

```ruby:app/models/user.rb
class User < ApplicationRecord
  connects_to database: { writing: :primary, reading: :primary }
end
```

# 動作確認のスクリプトを作成する

`ActiveRecord::Base.connection` と `User.connection` が違うことを確認し、 `while_preventing_writes` のブロック内では、DBへの書き込みができないことを確認します。

```ruby:scripts/while_preventing_writes.rb
puts User.count

if ActiveRecord::Base.connection.object_id != User.connection.object_id
  puts 'ActiveRecord::Base.connection != User.connection'
end

# ActiveRecord::Base.connection.while_preventing_writes do # Rails 6.0.0.rc1
ActiveRecord::Base.connection_handler.while_preventing_writes do # Rails 6.0.0
  User.create!(name: 'Taro')
end

puts User.count
```

# マイグレーションを実行する

```shell
$ bin/rails db:create db:migrate
```

# スクリプトを実行する

スクリプトを実行します。 `Write query attempted while in readonly mode:` のメッセージが出力され、書き込みが失敗することがわかります。

```shell
$ bin/rails runner scripts/while_preventing_writes.rb
Running via Spring preloader in process 81
0
ActiveRecord::Base.connection != User.connection
Traceback (most recent call last):
...
/usr/local/bundle/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:643:in `execute_and_clear': Write query attempted while in readonly mode: INSERT INTO "users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" (ActiveRecord::ReadOnlyError)
```

# ちなみに

Rails 6.0.0rc1 では、エラーにならず、保存できてしまいます。(6.0.0rc1 では、メソッドの定義場所が異なるため、 `ActiveRecord::Base.connection.while_preventing_writes` とする必要があります。）

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try109_while_preventing_writes

# 参考情報

* [Move while_preventing_writes from conn to handler](https://github.com/rails/rails/pull/36469)
HttpPostでファイル受信（PHP）

#はじめに
XAMPPのApacheを利用して、ファイル受信をしたかった。
コピペでPHPのファイル受信プログラムを作成したが、ファイルを受け取れず困ったのでメモ。

エラーコードを見ると1が返されており、ファイルサイズが大きすぎたことが原因だとわかった。
php.ini の upload_max_filesizeを書き換えて再起動することによって解決した。

送信側については書かない。

#リファレンス
[POST メソッドによるアップロード]
(https://www.php.net/manual/ja/features.file-upload.post-method.php)
[エラーメッセージの説明]
(https://www.php.net/manual/ja/features.file-upload.errors.php)

#アップロード用のphpファイル
```php:upload.php
<?php
//情報取得
$name = $_FILES["file"]["name"]; // ファイル名
$mimetype = $_FILES["file"]["type"]; // Content-Type
$filesize = $_FILES["file"]["size"]; // ファイルサイズ
$tmpname = $_FILES["file"]["tmp_name"]; // 一時ファイル名
$error = $_FILES["file"]["error"]; // エラー

//ログ
$file = 'log.txt';
$current = file_get_contents($file);
$current .= $name . "\n";
$current .= $mimetype . "\n";
$current .= $filesize . "\n";
$current .= $tmpname . "\n";
$current .= $error . "\n";
file_put_contents($file, $current);

//なければフォルダを作成
$target_dir = "imgs";
if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}

//保存
$filename = $target_dir . "/" . $name;
$result = @move_uploaded_file( $tmpname, $filename );

echo( $result );
?>
```
[TypeScript]Jest導入メモ

jestのインストール

```
npm i jest @types/jest ts-jest -D
```

package.jsonのscriptsを変更する

```json:package.json
{
    "scripts": {
        "test": "jest"
    },
}
```

`src/tests/` 配下に `xxx.test.ts` を作成する

```typescript:sum.test.ts
test('ok sum', () => {
    expect(sum(1, 2)).toBe(3);
});

test('ok sum multiple', () => {
    expect(sum(1, 2, 3)).toBe(6);
});

test('ng sum', () => {
    expect(sum(1, 2, 3)).toBe(10);
});

const sum = (...numbers: number[]) => {
    return numbers.reduce((previousValue, currentValue) => previousValue + currentValue)
};
```

テスト実行

```
npm t
```

実行結果
エラーケースがあると以下の様に出力してくれる

```typescript
 FAIL  src/tests/sum.test.ts (16.136s)
  ● ng sum

    expect(received).toBe(expected) // Object.is equality

    Expected: 10
    Received: 6

       8 | 
       9 | test('ng sum', () => {
    > 10 |     expect(sum(1, 2, 3)).toBe(10);
         |                          ^
      11 | });
      12 | 
      13 | const sum = (...numbers: number[]) => {

      at Object.<anonymous>.test (src/tests/sum.test.ts:10:26)
```

# 参考ドキュメント

https://doc.ebichu.cc/jest/docs/en/getting-started.html
05. n-gram

## 05. n-gram
リストなど）からn-gramを作る関数を作成せよ．この関数を用い，"I am an NLPer"という文から単語bi-gram，文字bi-gramを得よ．

###Go
```go
package main

import (
	"fmt"
	"strings"
)

//  文字単位の bi-gram
func ch_bi_gram(src string) []string {
	var res []string

	//	文字数ループ（１文字少なく）
	for i:=0 ; i<(len(src)-1);i++ {
		//	添字の文字と次の文字を連結
		res = append(res, string(src[i]) + string(src[i+1]))
	}

	return res
}

//  単語単位の bi-gram
func wd_bi_gram(src string) []string {
	var res []string

	//  単語単位で文字列を分割
	words := strings.Split(src, " ")

	//  単語数ループ（１配列少なく）
	for i:=0 ; i<(len(words)-1);i++ {
		//  空白で単語を区切ったため、空白を追加し単語を連結
		res = append(res, words[i] + " " + words[i+1])
	}

	return res
}

func main() {
	src := "I am an NLPer"

	//  文字単位の bi-gram
	res1 := ch_bi_gram(src)
	fmt.Printf("%q\n",res1)

	//  単語単位の bi-gram
	res2 := wd_bi_gram(src)
	fmt.Printf("%q\n",res2)
}
```


###python
```python
# -*- coding: utf-8 -*-

#   文字単位の bi-gram
def ch_bi_gram(src):
    res = list(range(0))

    #   文字数ループ（１文字少なく）
    for i in range(len(src)-1):
        #   添字の文字と次の文字を連結
        res.append(src[i] + src[i+1])

    return res

#   単語単位の bi-gram
def wd_bi_gram(src):
    res = list(range(0))

    #   単語単位で文字列を分割
    words = src.split(" ")

    #   単語数ループ（１配列少なく）
    for i in range(len(words)-1):
        #   空白で単語を区切ったため、空白を追加し単語を連結
        res.append(words[i] + " " + words[i+1])

    return res


src = "I am an NLPer"

#   文字単位の bi-gram
res = ch_bi_gram(src)
print res

#   単語単位の bi-gram
res = wd_bi_gram(src)
print res
```


###Javascript
```Javascript
//  文字単位の bi-gram
function ch_bi_gram(src) {
    var res = [];

    //	文字数ループ（１文字少なく）
    for (var i = 0; i < (src.length-1); i++) {
        //  添字の文字と次の文字を連結
        res.push(src[i] + src[i+1]);
    }

    return res;
}

//  単語単位の bi-gram
function wd_bi_gram(src) {
    var res = [];

    //  単語単位で文字列を分割
    var words = src.split(' ');

    //  単語数ループ（１配列少なく）
    for (var i=0;i<(words.length-1);i++) {
        //  空白で単語を区切ったため、空白を追加し単語を連結
        res.push(words[i] + " " + words[i+1]);
    }

    return res;
}

var src = "I am an NLPer"

//  文字単位の bi-gram
var chr = ch_bi_gram(src);
console.log(chr);

//  単語単位の bi-gram
var wd = wd_bi_gram(src);
console.log(wd);
```

## まとめ
次の「05. n-gram」 は他の方の解説を読むが難しい。
[[n番煎じ] 言語処理100本ノック 2015 第1章 with Python](https://qiita.com/3000manJPY/items/40dcb9994eedfa7f33dd) に結果が載ってた。

```
文字列(入力): I am an NLPer
文字バイグラム: ['I ', ' a', 'am', 'm ', ' a', 'an', 'n ', ' N', 'NL', 'LP', 'Pe', 'er']
単語バイグラム: ['I am', 'am an', 'an NLPer']
```
解りやすい。文章解読能力が無いことを痛感。

気になってる点。文章を空白で分割したがその空白を後で結合している部分。
これでいいのかなぁ。なんかカッコよくない気がする。


[トップ](https://qiita.com/naoshin1984/items/3d7814e2f8eb01eea8dd)
勤務評価Ａの新人エンジニアが伝える　トイレで読める5分ネットワーク基礎講座@　第１回

# はじめに
婚約を契機に、キャリアを再考してエンジニアに転職したIWAOです。
私の記事へアクセス頂き、ありがとうございます。

この記事を書くのは、「エンジニアはアウトプットを常に」との助言を実践するからです。

入社してから３カ月の研修期間を終え、
最高評価Aを頂きました。
常に学ぶ姿勢が大切だなと確信しています。

それでは、今回のアウトプットですが、
研修期間中に学んだコンピューターネットワークについての基礎を、
まとめながら書いていきます。

宜しくお願いします。

参考にした文献は、下記の通りです。

○3分間ネットワーク基礎講座　著者：網野衛二　氏　

##ネットワークについて

ネットワークとは
**何かと何かが繋がり何かを運ぶ網目状の網です**

なんか、なぞなぞみたいですね。

コンピューターネットワーク
ネットワークビジネス
物流ネットワーク
血管

いたるとこに、ネット(網)状の何かを運ぶ経路があります。

その中でもコンピューターネットワークとは何か、こちらを今から説明します。
私の記事を読むと未経験からネットワークエンジニアに転職できます。

なぜなら、読んでくれたら私の勤める商社系ＩＴ企業の人事担当者の連絡先をいつでも教えるからです。
希望者は連絡くださいw

##コンピューターネットワークの利点

利点は、通信媒体を活用して情報(データ)を通信して、
**リソースを共有する**
ことです。

リソースとは、ストレージやサーバー、個人のパソコンの有益な情報、ネット上の情報など、
本来であれば、限られた人しか利用できなかった物です。

そちらを共有して、みんなで利用出来るのが、ネットワークの利点となります。

##情報(データ)をどのように運ぶか

コンピューターネットワーク運ばれているものは情報(データ)です。

この情報(データ)は、ビット(bit)で表せられます。ビット(bit)とは情報量の単位です※binary digitの約らしい。

例えば、貴方のパソコンと私のパソコンを対面で直接繋ぎ、データを運ぶためには、下図の構成になります。

　貴方のＰＣ⇔貴方のＰＣのインターフェース⇔私のＰＣのインターフェース⇔私のＰＣ
　
　⇔　=　通信媒体　(ケーブル通信や無線通信など)

このようにデータをやり取りする際に必要な通信規約(通信する際のルール)が必要です。
それが！！**プロトコル　(通信規約)**です。

##通信方法

回線交換とパケット交換という、２つの方法があります。

大事なことは、**回線を共有**するにはどうするかです。

回線交換では、使用する回線が通信時には占有されてしまうので、
コンピューターネットワークでは、パケット交換により通信します。

パケットとは、データを小分けして運ぶイメージです。
小分けされたものを送信先で元のデータに戻します。

##コンピューターネットワークの構造

貴方のＰＣ⇔貴方のＰＣのインターフェース⇔私のＰＣのインターフェース⇔私のＰＣ

上記のように、２つのＰＣ(点)とＰＣ(点)が直接つながっている通信を、

**ポイントツーポイントネットワーク**と呼びます。

交際相手の携帯⇔交際相手の携帯のインターフェース
　　　　　　　　　　　　　　　　　　　　　　↑
　　　　　　　　　　　　　　　　　　　　　　↓
貴方のＰＣ⇔貴方のＰＣのインターフェース⇔私のＰＣのインターフェース⇔私のＰＣ
　　　　　　　　　　　　　　　　　　　　　　↑
　　　　　　　　　　　　　　　　　　　　　　↓
高校時代の友人のＰＣ⇔高校時代の友人のＰＣのインターフェース

上記のように、私のパソコンに様々な機器(点)がつながっている通信を
**マルチアクセスネットワーク**と呼びます。

この**ポイントツーポイントネットワーク**と**マルチアクセスネットワーク**が様々につながることで、コンピューターネットワークは構成されます。

##ＬＡＮとＷＡＮ

　狭い範囲(構内)で自分の責任で作るネットワークがＬＡＮ(ローカルエリアネットワーク)

　広い範囲で電気通信事業者(ＩＳＰ)から通信媒体(ケーブルなど)を借りるネットワークがＷＡＮ(ワイドエリアネットワーク)

**世界規模の最大のＷＡＮがインターネットだ！！**と参考書に書いてありました。

なんか壮大ですね。

第１回目は、
**以上です**。

# おわりに

読んでいただき、ありがとうございます。
毎回、
5分程度で読めるぐらいのボリュームで書いていきたいと考えてます。

次回はＯＳＩ参照モデルやＴＣＰ／ＩＰモデルについて書きます。

インフラについては、どの分野のＩＴ関係者も基礎知識が役立つと考えます。
未経験から転職した私だからこそ書ける、柔らかい文言で今後もまとめたいと考えます。

今後ともよろしくお願いします。

お終い。
情報処理安全確保支援士のオンライン講習Bを受講しました

情報処理安全確保支援士に２年目に義務付けられているオンライン講習Bを受講しました。

１年目のオンライン講習Aは、 こちら.
  [情報処理安全確保支援士のオンライン講習を受講しました](https://qiita.com/stoneriverheart/items/2ab8f489248cc353d407)

 
学習内容は、以下になります。

1. 情報処理安全確保支援士として認識しておくべき脅威や対策に向けての情報収集・活用について
2. 「セキュリティ設定共通化手順SCAP」概説【前編】
3. 「セキュリティ設定共通化手順SCAP」概説【後編】
4. 脆弱性情報の読み方、扱い方
5. ユーザ教育と内部監査
6. 法令遵守・契約履行

の６項目になっています。

---


## 情報処理安全確保支援士として認識しておくべき脅威や対策に向けての情報収集・活用について

情報処理安全確保支援士としての人材像から、日々求められる情報収集、活用例等を学習します。

## 「セキュリティ設定共通化手順SCAP」概説【前編】

SCAP(Security Content Automation Protocol) について学習します。

## 「セキュリティ設定共通化手順SCAP」概説【後編】

CVSS, XCCDF, OVAL, FDCCについて学習します。

## 脆弱性情報の読み方、扱い方

職務ごとの脆弱性情報の読み方・扱い方を学習します。

## ユーザ教育と内部監査

内部監査、情報セキュリティ教育に関して学習します。
内部監査人として情報処理安全確保支援士が活動する時のポイント、ユーザ教育の必要性と実施方法等を学習します。

## 法令遵守・契約履行

情報処理安全確保支援士が理解しておくべき法律、法令、契約等を学習します。

---

Qiitaの前回記事が前回のオンライン講習A受講時になっており、最近Qiitaに記事を書いていないことを痛感しつつ、
業務でセキュリティを意識していないと忘れていることが多く、もう少し、セキュリティに関連する知識、情報等を日々取集する意識を持たねばと痛感しました。
Centos8 にMysql-pythonをインストールする

詰まったのでメモ。
Centos7までは以下でインストールできた。

```shell:Centos7系まで
yum install Mysql-python
```

Centos8になるとそもそも「Mysql-python」というパッケージがなくなったらしい。
参考：https://community.centminmod.com/threads/centmin-mod-centos-8-compatibility-worklog.18372/

Centos8からは以下でインストールする
（※python2系を使うなら数字部分を2にする）

```shell:Centos8系
yum install python3-PyMySQL
または
dnf install python3-PyMySQL
```
個人用ポータル - Tech系（思い出し＆勉強用）

参考にさせてもらっている記事類（随時追加）

# 開発環境
最強のMac開発環境【2019年版】
https://qiita.com/papi_tokei/items/6734a814406a787c5997

pyenv-virtualenvでディレクトリ単位のpython環境構築
https://qiita.com/niwak2/items/5490607be32202ce1314

claspの導入(Mac)
https://qiita.com/qwq00/items/2264ffee87664e75318c


# GitHub系
Gitを使ってPull Requestを投げるまで
https://qiita.com/takamii228/items/80c0996a0b5fa39337bd

【初心者向け】git fetch、git merge、git pullの違いについて
https://qiita.com/wann/items/688bc17460a457104d7d

github でブランチ・commit間の diff を見る
https://qiita.com/fantasista_21jp/items/9419ca4ab3bb8e1ee4c5


# Python
pythonでのcsvファイルの読み込み
https://qiita.com/motoki1990/items/0274d8bcf1a97fe4a869

Pythonのdocopt使い方メモ
https://qiita.com/ymdymd/items/651245d80964393b12c5


# JS関連
npmとpackage.jsonが良く分からなかったので独自目線で纏めた
https://qiita.com/aya_akatsuki/items/f70d0d1668ef867f7256

npm自体のバージョンを上げる
https://qiita.com/n0bisuke/items/b2704b6ebb84f21c03c1

ES2015(ES6) 入門
https://qiita.com/soarflat/items/b251caf9cb59b72beb9b

【Node.js入門】exports / module.exportsによるモジュール機能の使い方まとめ！
https://www.sejuku.net/blog/80173

イマドキのJavaScriptの書き方2018
https://qiita.com/shibukawa/items/19ab5c381bbb2e09d0d9

JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる
https://qiita.com/YoshikiNakamura/items/732ded26c85a7f771a27

validator
https://wp-kyoto.net/npm-install-validator/

Random文字列
https://gist.github.com/6174/6062387

sync-request
https://designetwork.daichi703n.com/entry/2016/11/16/node-js-sync-request


# API
Amazon API Gateway
https://qiita.com/leomaro7/items/66ea3233097fa410fef9


# Slack
Slackでリアクションをつけた人を、Googleカレンダーの予定に自動で招待するワークフローの紹介
https://note.com/operando_os/n/n48e16020c0cd


# ドキュメント系
ディレクトリ構成図を書くときに便利な記号
https://qiita.com/paty-fakename/items/c82ed27b4070feeceff6

Slackの /remind の文言は複数行で記述する方法がある
https://shinkufencer.hateblo.jp/entry/2019/04/03/000000
nuxt generate した後のページでエラーが発生する

## はじめに
Diverseのアドベントカレンダー、5日目担当のshiranuikです。
私は現在Youbrideというサービスの、WebフロントエンドのNuxt化を進めています。
現状のYoubrideでは、古き良きPerlによってHTMLを書き出しています。
いきなり全ては捨てられない……でも今後を考えるとフロントエンドとバックエンドは切り離せるようにしたい……。
そこで「**nuxt generate** だ！」
_※このあたりの具体的なお話は、日と場所を改めてそのうち公開されることと思います。_

今日はNuxt化に日々取り組んでいて、最近一番困った件を紹介します。

## nuxt generate 後に謎のエラー
`nuxt dev`実行ではエラーが出ないのに、generate後のページにアクセスするとJavaScriptのエラーが出てる！
……というのがそもそもの発端です。出ていたエラーはこんな感じ。

```plaintext:consoleに出ていたエラー
Failed to execute 'appendChild' on 'Node': This node type does not support this method. 
```

### なんだろう？
子要素を追加できない、つまりNuxtがViewを生成するときに失敗しているっぽい。
ダミーデータを使っているローカル開発環境では発生しないので、多分PerlからNuxtに注入しているデータが悪い……のかもしれない？

試しに渡すデータを空っぽや静的なものにしてみる。
⇒ エラー変わらず。注入しているデータの問題ではない。

ではどこかHTMLの構造に問題があるかもしれないから、一度まっさらな状態にしてみよう。
⇒ エラーが消えた！

少しずつ戻してどこの箇所が問題か探る。
⇒　Formタグ……？

ここでようやく、実際に表示されているHTMLとdistにある生成されたHTMLを比べてみました。
すると、何か知らない`<input type='hidden' name='hoge' value='fuga'>`が追加されている！！ これか！！！

### どうしてこうなった
該当のタグはPerl側でFormタグがあるときに問答無用で追加していました。
Nuxt側が覚えているHTML要素と生成されたHTML要素が違うと該当のエラーが発生するようです。
（※完全に描画する前にJavaScriptの処理が止まってしまうため、データが取得できなかったり、計算が止まってしまったりの状態になります。そのため、上記エラー以外にも、slot周り等のエラーが出たりもしていました）

該当のタグは埋め込まないといけない。要素の数を揃えないといけない。どうしよう。

### ではこうしよう。

```html:sample.vue
<templete>
 <form method="post">
  <input type="hidden" name="hoge" id="hoge"/>
  <input type="mail" name="mail"/>
  <input type="password" name="password"/>
  <input type="submit" value="login"/>
 </form>
</template>

<script>
 export default {
  name:'login',
  data(){
    return {
      hoge:null,
    }
  },
  /** mountedに入る前に、hogeにはサーバから渡されたデータが入っている **/
  mounted(){
    if (!this.hoge) {
      document.getElementsById('hoge').forEach((value) => {
        value.value = this.hoge;
      });
    }
  }
```

Nuxtの該当箇所に空っぽの`<input type='hidden' name='hoge'>`を用意します。
これで一旦エラーは出なくなりますが、DOM生成後には本来埋め込んでいた値が消えてしまっています。
DOMの準備が終わった`mounted`の中で、別の手段で受け取っていた値を流し込んでいます。

## まとめ。
nuxt generate後のHTMLに何か追加するときは、エラーになることがあるので気をつける。
空の要素を用意しておき、後から値を代入すると問題なく動く。

generate後のHTMLに後から何か挿入したり書き換えたりは通常あまり無いと思うのですが、原因不明のJavaScriptエラーが出たときにでも思い出してみてください！
AWS上に、Re:dashを導入する。

# 未経験エンジニアがRe:dashをAWS上に構築してみた
株式会社パーソンリンクにエンジニア未経験で入社して3週目の高島です。<br>高校では、情報技術科に所属していました。授業でC言語やJavaの基本文法を学びました。高卒で東京に上京してきて、印刷系の仕事を約５年半やっていました。<br>しかしながら、今日のIT業界は、キャッシュレス決済、SNSなど、めまぐるしいスピードで進化していることを実感しました。上京する前の自分に言っても信じてもらえないようなことが、実際に起こっている現状を見て、いわゆる「ゆとり世代」として、そのスピードについていかなければいけないと危機感を持ったと同時に、その開発に携わってみたいと思い、転職を決意しました。<br>自分と同じように、未経験からエンジニアを目指している方々の刺激に少しでもなれたらと思いますので、よろしくお願いいたします。<br>今担当しているプロジェクトにて、運用・保守業務を今後していくのですが、それにあたってAWS上でRedashを導入することになったので、その過程をメモしました。初心者なので、至らない点たくさんあると思います。間違いなどありましたら、ご指摘いただけると幸いです。今回は、MySQL (Amazon RDS)を利用できるようにするところまで進めました。

## Re:dashとは
オープンソースのダッシュボードツールです。自分なりに解釈した結果、データベースなどのデータを、表や、グラフにすることができるツール（？）です。SQLを実行することもできます。
定期的にグラフを更新する機能があるので、リアルタイムでグラフ化した情報を見ることができそうです。
## 参考にさせていただいた記事
> [AWSにRedashを設置](https://qiita.com/hujuu/items/8e8d6b61b03860302e51)

## やり方
### Redashの公式ホームページから、AMIを選択
https://redash.io/help/open-source/setup#
**awsap-northeast-1（東京）**を選択。選択すると、ステップ２の、インスタンス選択画面に遷移します。

### インスタンスタイプの設定

無料利用枠から外れてしまいますが、t2.small以上を選択してください。公式の説明書には、t2.small以上推奨と書いています。

### セキュリティーグループの設定
３〜５をそのままで、セキュリティーグループの設定です。画像の通り、SSHに加え、HTTP,HTTPSも追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/f26f09e2-c993-dd82-0ec5-e30e820218c8.png)
ソースと書いてある部分に、自分のIPアドレスを入れます。
自分のIPアドレスは、ブラウザ上でIPアドレスと検索すれば、出てきます。
https://www.cman.jp/network/

### RDSの設定
1. AWSのコンソールから、**RDS**を選択。
2. 左カラムににある、**データベース**を選択。
3. 自分のデータベースを選択し、**接続とセキュリティ**のタブ
4. 画面中央右側にある、**VPCセキュリティグループ**をクリック
5. 画面遷移するので、下部にある、**インバウンド**タブを選択、編集ボタンをクリック
6. 先ほどの**セキュリティーグループの設定**にて作成した、セキュリティーグループを追加。

## Re:dashにログイン
Redashにログインしていくのですが、ここでつまづきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/fa0e7557-f56a-b241-7683-85b721ad8d52.png)
本来ならこのページに行きたいのですが、Redashのホームページからログインしようとすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/7a373b79-364c-c2a9-7851-90cf2ff0c367.png)
本来入力したいメールアドレスとパスワードとは違う情報を入力する画面に行ってしまいました。

以下の手順で操作すると解決することができました。
1. AWSコンソールから、**EC2**を選択し、先ほど作成した、自分のインスタンスを選択
2. 画面右下に、**パブリック DNS (IPv4)**があるので、そのURLのページに行くと、直接Redashのサインアップページに遷移する
3. 自分の情報を入力し、サインアップを完了させる


## データベースに接続
1. 右上のはてなマークの右のボタン
2. Data Sourcesのタブ
3. + New Data Source
4. MySQL (Amazon RDS)を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/49b1d3f5-8cb9-f565-86ed-2cc55ea9076b.png)

情報を入力していきます。ここでつまづきました。
hostの欄に、何を入力すればいいかわからなかったです。
以下の方法で解決しました。
- host　の部分は、AWSコンソールから、RDSに飛んで、自分のデータベースを選択。
**接続とセキュリティ**タブの、**エンドポイント**が、hostにあたります。

これですべての設定は終わりです。さて無事に動作できるでしょうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/d46bfd2f-0584-fd4b-a52a-cf9a33f180c4.png)

入社3週間の未経験エンジニアでもなんとか環境を構築することができました。
いざ、右も左もわからない状態で環境構築をしてみると、まずはAWS周りの単語の理解が難しかったです。記事通りにやっているのに、目的の画面に遷移しないのは何故なのか、全然見当もつきませんでした(^_^;)<br>記事を見落としていたり、公式ドキュメントに書いてあるところを飛ばして読んでいたりと、少し焦っていたので、落ち着いてやっていきたいと思います。目的のリソースに対しての情報が少ない場合は、公式ドキュメントを翻訳していくというのは、避けて通れないので苦手意識を少しでもなくしていきたいです。

明日も、高島が担当させていただきます。
最後まで読んで頂き、ありがとうございました。
GithubActionsでCircleCI置き換えてFirebaseにデプロイするのにてこずった

# TL;DR

`create-react-app` でSPA作って、`Firebase` でバックエンドとホスティングその他用意して、`Github` でソース管理してCI/CDを`GithubActions` 使えばかなりコンパクトにウェブアプリ作る基盤できるでしょ。
って気軽な気持ちで挑んだら細々つまづきポイントがあった話。
FirebaseをGithubActionsからデプロイした話なのでReact要素はないです。
主にGithubActionsハンズオンとfirebaseをGithubActionsでデプロイするときのメモ

- secretsに`firebase login:ci`したトークンを設定する
- `firebase-tools`を`devdependencies`に追加しておかないとCIの時の環境に`firebase-tools`が無くて詰む
- firebase deploy コマンドはhosting以外もinitしてるとエラーの原因になるので(今回はホスティングにデプロイすることが目的のためとりあえず)`--only hosting`する

上記3点が以下で適当に書き散らかされてる内容です。

# したかったこと
create-react-appでサクッと用意したアプリをmasterへのコミットに応じて `npm run build` して `firebase deploy`でhostingに公開してくれる上にバックエンド要素も全部入りなreact+firebase+CIのモノリポを用意したかった

# ディレクトリ構成
<img width="173" alt="Screen Shot 2019-12-02 at 10.41.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60407/7f57686e-07b2-a030-de85-391cd0a44de7.png">

`create-react-app`したあとに`firebase init`してとにかく全部入れたみたいな感じ。

# ハマり...そして解決へ

とりあえずGithubActionsをNode用で用意
Secretsに `firebase login:ci` でゲットしたトークンも設定
そしてコミットしてプッシュ！走るCI！そしてエラー！！！！！！！

エラーメッセージにはこんな内容
`./node_modules/.bin/firebase: No such file or directory`

なるほど`devdependencies`じゃねーの？

firebase-toolsってグローバルに入ってるものをそのまま使ってたため忘れてた。
(さらっと書いたけどこの事実に気づくまでに時間がかかった時点でnpm慣れしてないことがバレる。)

`npm add --dev firebase-tools`したら次は違うエラーだぜ！！

```console:error-message

Run ./node_modules/.bin/firebase deploy --only hosting --token=***
  ./node_modules/.bin/firebase deploy --only hosting --token=***
  shell: /bin/bash -e {0}

Error: No project active, but project aliases are available.

Run firebase use <alias> with one of these options:

  default (this-project)
  alias-name-of-project (this-project)
##[error]Process completed with exit code 1.

```

と言う感じのエラーメッセージが出たのでprojectの指定もつける。

結果できたymlはこちら

```yaml:nodejs.yml

name: Node CI

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - name: npm install, build
        run: |
          npm install
          npm run build
      - name: deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy --only hosting --project default --token=${{ secrets.FIREBASE_TOKEN }}

```

もっとスマートと言うか必要最低限の記載オンリーの設定にもできると思うけど慣れてないし理解が追いついてないので、
デフォルトのyamlをちょっと変えただけ。


# まとめ

そもそもci/cdが何をしてるか、コンテナが使い捨てられるようなデプロイフローの中で行われていることをきちんと把握してなかったせいでfirebase-toolsが無いエラーとかに詰まったりして時間を無駄にした。

firebaseのコマンドラインツールに慣れていないためにさらに困惑した
このリポジトリはこのままstep by stepで簡単なCRUD、ログイン、その他を実装してFireStore, Storage, Functions, authenticationなんかを使ったウェブサービスとして構築し、テストの追加とかもして一塊のプロダクト開発環境として構築するのが目標なので、この先もハマりが生まれたり、
あんまりこの辺りのツールや知識に強く無い人の参考になる情報が出せたらこのつまづきの供養になるので継続的に供養をしていきたい。

とりあえずGithubActionsいいよ！というお話
Amazon Athenaのユーザー定義関数(UDF)のPreview版を試してみた

Amazon Athenaが遂にユーザー定義関数(UDF)をサポートするようです。
[Amazon Athena Adds support for User Defined Functions (UDF)](https://aws.amazon.com/jp/about-aws/whats-new/2019/11/amazon-athena-adds-support-for-user-defined-functions-udf/)
独自に関数を作成する事で、ビルトイン関数では不可能な処理を実現できるようになります。
Preview版が公開されたので使い勝手を確かめてみました。
# まとめ
* UDFはJava言語の[Athena Query Federation SDK](https://github.com/awslabs/aws-athena-query-federation/)で開発し、AWS Lambdaに登録する
* Athenaから利用する際の構文は以下

```sql:
USING EXTERNAL FUNCTION <function name>(col1 <type>) RETURNS <type>
LAMBDA '<lambda name>'
SELECT ...
```
* 1回のLambda関数で複数のレコードがまとめて処理される為、リクエスト料金面の問題は現時点ではなさそう

# Amazon Athenaとは
Amazon S3内のデータを標準SQLを用いて分析できるサービスです。
# 試してみた
2019/11/27現在、Preview版のUDFはus-east-1リージョンでのみ利用可能です。

UDFの作成はJava言語の[Athena Query Federation SDK](https://github.com/awslabs/aws-athena-query-federation/)を用いて行います。

既存ソースコードに以下の関数を追加して、jarファイルをビルドします。

```java:aws-athena-query-federation/athena-udfs/src/main/java/com/.../udfs/AthenaUDFHandler.java
public Long increment(Long input)
{
    System.out.println("input:" + input);
    return input + 1;
}
```

作成したUDF(athena-udfs-1.0.jar)をus-east-1リージョンのAWS Lambdaに登録します。
![lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/c6c14e6e-9044-5753-0b44-6aa9bb8eca1e.png)

AthenaでPreview版のUDFを利用する為に、"AmazonAthenaPreviewFunctionality"という名称のワークグループを作成し、作成したワークグループに切り替えます。
![workgroups.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/8084573c-9b67-0696-4ca9-6736facbdeaa.png)


以下のクエリを実行します。

```sql:
USING EXTERNAL FUNCTION increment(col1 BIGINT) RETURNS BIGINT
LAMBDA 'athena_udfs_test'
SELECT v,increment(v) AS v_
FROM UNNEST(SEQUENCE(1,10000)) AS t(v)
```

# 結果
![query.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/8d8ba914-f2c2-0681-edfc-c5f5b28d333d.png)

LambdaのCloudWatchログを見る限り、1回のLambda関数で多数の行がまとめて処理されている様子でした。1レコード毎にLambda関数が実行されるとリクエスト料金が跳ね上がる事を懸念していたのですが、その懸念は(あまり)なさそうです。
![cloudwatch_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/46e04563-5977-1d94-e850-537123f959e8.png)
![cloudwatch_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/09b35043-9249-cc0f-f923-2347837ac870.png)
# 所感
待ちに待った機能が遂に出た、という印象です。これでビルトイン関数だけでは手が届かなかった事を実現できるようになります。
現時点での不満は、都度UDFを宣言するのに手間がかかる事でしょうか。この点は事前登録する機能が今後リリースされる事に期待します。
git リモートリポジトリーの復旧

git push している最中にネットワークエラーとサーバーの再起動が重なってリモートリポジトリが動かなくなってしまいました。
その際にローカルのリポジトリーが最新の状態でしたので、ローカルからリモートを復旧しました。

## 対処方法

- リモート側に新規のリポジトリを作成。

```sh:
cd リポジトリのディレクトリー(/var/test/)
mkdir new_repo.git
cd new_repo.git
git init --bare --shared
```

- ローカルの設定に新しいリモートリポジトリパスを追加 new とする。

```vi:
[remote "new"]
	url = ssh://user_name@servername:22/var/test/new_repo.git
	fetch = +refs/heads/*:refs/remotes/new/*
```

- 新しいリポジトリにローカルからpush

```sh:
git push new master
```
- マスターリポジトリの置き換え

```sh:
cd /var/test/
rm -rf origin_repo.git
mv new_repo.git origin_repo.git
```

- ローカルの設定に新しいリモートリポジトリパス new を削除する。
UUID について

## Format
+ xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx
 Nの値は 8,9,A,Bいずれか 全て０のUUIDがあるため、 [089aAbB]でマッチする

+ xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
 Mはバージョン 1~5

xは１６進法の表現

## 重複の確率について
乱数に基づく UUIDの場合、5.3×10^36通り存在
２つのIDが一致するまでの期待値が、2^61個のID生成が必要
  宝くじ当たるぐらいですかね・・・。


## UDID UUIDの違い （ざっくり調査)
- UDID(Unique Device IDentifier)

iOS 端末ごとの固有ID 現状の取得は非推奨でUUIDを取得する

- UUID(Universally Unique IDentifier)

理論上重複はない固有のID
Macのターミナルで uuidgen をすると生成できる

### 参考
[[memo]UDID/UUID/UIIDなどとiOS6の新IDの違い](https://tanamon.hatenablog.jp/entry/20120924/1348491831)

# 参考リンク
[RFC 4122](https://tools.ietf.org/html/rfc4122)
[UUID v4](https://en.wikipedia.org/wiki/Universally_unique_identifier)
[UUID wikipedia](https://ja.wikipedia.org/wiki/UUID)
[Node.js]Expressのミドルウェアの基本

## はじめに
この記事では、Expressを使いこなす上で必須となる、「ミドルウェア」について説明します。Expressをこれから使い始める方、使い始めて間もない方を対象にした基本的な内容になります。

現在の最新バージョンである4.17.1で動作を確認しています。

## Expressとミドルウェア
[Express](https://expressjs.com/)はNode.js環境で使われる最も人気のあるWebアプリケーションフレームワークのうちの一つです。最小限の機能を提供する薄いフレームワークになっていて、ユーザーの自由度が高い点が特徴的です。（例えば、データベースアクセス、認証をExpressは提供しません。）

また、[ドキュメントにある通り](https://expressjs.com/ja/guide/using-middleware.html)、「Expressアプリケーションは一連のミドルウェア関数呼び出し」といえます。つまり、ユーザーからのHTTPリクエストを受信しレスポンスを返すまでに、いくつかのミドルウェア関数を通過し、リクエストからレスポンスまでのサイクルが完了します。


## ミドルウェアとは

ミドルウェアとは、リクエストオブジェクトとレスポンスオブジェクトを受け取り、任意の処理を行う関数です。また、「Expressは一連のミドルウェア関数の呼び出し」と言われるように、次のミドルウェアへと処理を継続するか、もしくはリクエストレスポンスサイクルをそこで終了させるかのいずれかを行います。

次の関数を見てください。

```js
/*
 ドキュメントを元に作成
*/
var myLogger = function (req, res, next) {
  // 何か処理を行う
  console.log('LOGGED')

  // 次のミドルウェアに処理を移す
  next()
}
```

この例では、"LOGGED"の文字列を表示した後、nextを使って、次のミドルウェアへと処理が流れていきます。
実際の使い方とリクエストレスポンスサイクルを終了する例については、この後紹介します。

## アプリケーション全体（複数のミドルウェア関数を使う）

次は、二つのミドルウェア関数を使う例です。expressモジュールをインストール済みであれば、このまま実行可能です。(`npm install express`)

```js:app.js
/*
 ドキュメントを元に作成
*/
var express = require('express')

// アプリケーションオブジェクトの作成
var app = express()

// ミドルウェアの定義
var myLogger = function (req, res, next) {
  console.log('LOGGED')
  // 次のミドルウェアへ
  next()
}

// ミドルウェアの読み込み
app.use(myLogger)

// パスを限定してミドルウェアを適用
app.get('/', function (req, res) {
  // ミドルウェア関数の連鎖はここでおしまい
  res.send('Hello World!')
})

app.listen(3000)
```


ミドルウェア関数を読み込む順序も重要です。上記の例では、`res.send`を含むミドルウェア関数を先に読み込んでしまうと、myLoggerは実行されません。`res.send`で一連のサイクルが終了してしまうからです。

## サード・パーティー・ミドルウェアを使う

先ほどの例のように自作でミドルウェア関数を作成することができますが、頻繁に行われる処理については、サード・パーティー・ミドルウェアが存在します。

例えば、リクエストボディのJSONへの変換、cookieの読み取り、認証処理、ヘッダーの操作などです。
[ここ](https://expressjs.com/ja/resources/middleware.html)に一覧がまとまっています。

読み込ませ方は、自作ミドルウェアの場合と変わりません。たとえば、"cookie-parser"の場合は次のようになります。

```javascript
var cookieParser = require('cookie-parser')
app.use(cookieParser())
```

設定方法等は各モジュールによって違いますので、それぞれのドキュメントを参照してください。

以上です。


## 参考資料
* [公式サイト](https://expressjs.com/ja/)
    * [ミドルウェアの使用](https://expressjs.com/ja/guide/using-middleware.html)
    * [Express アプリケーションで使用するミドルウェアの作成](https://expressjs.com/ja/guide/writing-middleware.html)
ELB配下のEC2を一定確率で安全にシャットダウンする

# ELB配下のEC2を一定確率で安全にシャットダウンする


## やること
ELB配下のEC2インスタンスを

1. 一定確率以上で
1. 安全に(ELBからのトラフィックをこぼすことなく)

シャットダウンします

## 用途
1. 長時間起動しているとメモリリークするアプリケーションのワークアラウンド
1. 何らかの理由でEC2のIPを変更したい
1. 何らかの理由でEC2を1から立て直したい(ElasticBeanstalk環境のみの話ですが)

他にもなにかあれば教えてください！

## 環境
- ALB
- EC2(Amazon Linux)
- bash
- aws-cli
- ElasticBeanstalk
- jq

## 結論
このシェルをEC2インスタンスのcronに仕込めばn%の確率でシャットダウンします。

```bash:random_shutdown.sh
#!/bin/sh -vx
# Configuration
PERCENTAGE=5
SHUTDOWN_WAIT_TIME=300

# Execute with a probability of n% or more.
if [ $(($RANDOM % 100)) -lt $PERCENTAGE ]; then

    # Get instance-id(myself) and loadblancer-name
    INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
    LB_NAME=`aws elb describe-load-balancers --region ap-northeast-1 |jq -r '.LoadBalancerDescriptions[] | select( .Instances[].InstanceId == "'${INSTANCE_ID}'") |.LoadBalancerName'`
    echo My instance-id is ${INSTANCE_ID}
    echo My loadbalancer-name is ${LB_NAME}

    # Deregister ec2instance(myself)
    aws elb deregister-instances-from-load-balancer --region ap-northeast-1 --load-balancer-name ${LB_NAME} --instances ${INSTANCE_ID}

    # Terminate myself
    sleep $SHUTDOWN_WAIT_TIME
    shutdown -h now;
fi
```


## 説明
### 1. Randomに処理をするかどうか決める部分

```bash
if [ $(($RANDOM % 100)) -lt $PERCENTAGE ]; then
  # 行いたい処理
fi
```
シェルスクリプトでは、$RANDOMを参照すると 0~32767の乱数を取得できる。

100で割った余りを求めることで(0 ~ 99)の数を取得することができる。
乱数が事前に指定した値($PERCENTAGE)より低い範囲だった場合とする事で、指定確率で処理を実行できます。

### 2. meta-dataから自身のinstance-idを取得する

```bash
# Get instance-id(myself) and loadblancer-name
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
```

2. meta-dataからELBの名前を取得する

```bash
LB_NAME=`aws elb describe-load-balancers --region ap-northeast-1 |jq -r '.LoadBalancerDescriptions[] | select( .Instances[].InstanceId == "'${INSTANCE_ID}'") |.LoadBalancerName'`
```

jqについては[こちら](https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af)が参考になります。

### 3. EC2(自分自身)をELBから切り離す

```bash
aws elb deregister-instances-from-load-balancer --region ap-northeast-1 --load-balancer-name ${LB_NAME} --instances ${INSTANCE_ID}
```

EC2のロールには適切なポリシー(elasticloadbalancing:DeregisterTargets)を付与しておく必要があります。


### 4.shutdownコマンドでEC2インスタンスを落とす

```bash
# Terminate myself
sleep $SHUTDOWN_WAIT_TIME
shutdown -h now;
```

EC2インタンス上での処理が終わるまで、一定時間待ってから落とします。

## 終わりに
小ネタですが、Qiita初投稿してみました。
これからもちょこちょこあげていこうと思います。