OmniAICreator/Qiita-1.07M huggingface dataset:
Lambdaでmiddleware実装 Go編

初めてのGoでなれないところも多く悪戦苦闘していますが、共通処理を外に出してメンテナンス性やコード可読性をあげたいと思い、middlewareを実装してみました。

## middleware用のコード

```golang:middleware.go
package middleware

import (
	"github.com/aws/aws-lambda-go/events"
)

type Handler func(events.APIGatewayProxyRequest) (interface{}, error)

func Middleware(next Handler) Handler {
	return Handler(func(request events.APIGatewayProxyRequest) (interface{}, error) {
		return next(request)
	})
}
```
handlerについての公式ドキュメントはこちら
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/golang-handler.html


## 実際に組み込んだサンプルコード

```golang:main.go
package main

import (
	"fmt"
	"github.com/akihiro-moriwaki/lambda-middleware-go"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)


func handler(request events.APIGatewayProxyRequest, world string) (events.APIGatewayProxyResponse, error) {
	return events.APIGatewayProxyResponse{
		Body:       fmt.Sprintf("Hello %s", world),
		StatusCode: 200,
	}, nil
}

type EventHandler func(events.APIGatewayProxyRequest, string) (events.APIGatewayProxyResponse, error)

func testEventHandler(h EventHandler) middleware.Handler {
	return func(request events.APIGatewayProxyRequest) (interface{}, error) {
		return h(request, "world")
	}
}

func main() {
	lambda.Start(
		middleware.Middleware(
			testEventHandler(
				handler,
			),
		),
	)
}
```
https://github.com/akihiro-moriwaki/lambda-middleware-sample

EventHandlerの引数に色々渡して行きます

```golang
type EventHandler func(events.APIGatewayProxyRequest, string) (events.APIGatewayProxyResponse, error)
```

Lambdaのstart、デフォルトだと

```golang
lambda.Start(handler)
```

こんな感じで、middlewareで挟みます。

```golang
lambda.Start(
	middleware.Middleware(
		testEventHandler(
			handler,
		),
	),
)
```
「world」の文字列が渡され、レスポンスは「Hello world」となります
次は実用的な例で

## DB接続をMiddlewareでやると

```go:main.go
package main

import (
	"database/sql"
	"fmt"

	"github.com/akihiro-moriwaki/lambda-middleware-go"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(request events.APIGatewayProxyRequest, db *sql.DB) (events.APIGatewayProxyResponse, error) {
	defer db.Close()
	return events.APIGatewayProxyResponse{
		Body:       fmt.Sprintf("Hello world!"),
		StatusCode: 200,
	}, nil
}

type EventHandler func(events.APIGatewayProxyRequest, *sql.DB) (events.APIGatewayProxyResponse, error)

func dbEventHandler(h EventHandler) middleware.Handler {
	return func(request events.APIGatewayProxyRequest) (interface{}, error) {
		db, err := sql.Open("mysql", "user:password@tcp(host:port)/dbname")
		if err != nil {
			panic(err.Error())
		}
		return h(request, db)
	}
}

func main() {
	lambda.Start(
		middleware.Middleware(
			dbEventHandler(
				handler,
			),
		),
	)
}

```

簡単に実装しているのでもっと良い方法があれば教えてください


## コード
コードはご自由にどうぞ、自己責任でお願いします。
変更したり消したりするかもしれませんので使う場合はコピーして使ってくださいね

https://github.com/akihiro-moriwaki/lambda-middleware-go
https://github.com/akihiro-moriwaki/lambda-middleware-sample
はじめての投稿

具体的で簡潔なタイトルをつける
記事のタイトルは、記事のページだけでなくQiitaのフィードやGoogleの検索結果にも表示されます。タイトルを見ただけで記事の中身を想像できるようにしましょう。

具体的なタイトルをつけることで、特定の情報を探している人が記事を見つけやすくなります。

例：

「Rubyメモ」→「Rubyの定数探索はスコープと継承関係のどちらが優先されるか」
「正規表現でハマった」→「RubyとJavaScriptの正規表現では複数行モードの意味が違う」
「OpenSSLのバグ」→「CentOS 6.5でOpenSSLのHeartbleedバグにパッチを当てた」
環境や前提条件を説明する
記事で取り上げたソフトウェアのバージョンは何か、記事中のコードを実行するためにはどんな手順が必要かを書いておくと、自分の環境に当てはまるかどうかを後から読む人が判断しやすくなります。

例：

この記事ではCentOS 6.5にインストールしたRuby 2.2を使っています。
コードを実行するためには http://... で紹介されている設定ファイルが必要です。
コマンドライン引数に与えるユーザー名は適宜読み替えてください。
また、適切なタグをつけることで記事を見つけやすくなります。ある言語やライブラリの特定のバージョンについて話をするときは、タグにバージョンをつけてみましょう。例： Ruby:2.2

引用元や参考元へのリンクを書く
[Rails] ルーティングの一覧を見る方法

```routes.rb``` で設定されたパスとHTTPメソッドの一覧を確認したいとき、下記のコマンドを実行すると見ることができます。

```
$ bin/rails routes
```


オプション```-c```を使ってコントローラ名を指定すると、そのコントローラへのパスとHTTPメソッドのみを表示できます。

例えば```members_controller.erb``` のルーティングを見たいときは、

```
$ bin/rails routes -c members
```
[shell]ディレクトリのファイル内の文字列を置換してコピーする

# 環境

* Mac Catalina
* bash

# やろうとしてること

`/sample/`ディレクトリ内にあるテキストファイルの中身を`cat`から`dog`に書き換えてファイルを新規作成する。

```bash:/sample
# copy.sh 実行前
sample
|- copy.sh
|- aaa.txt
|- bbb.txt

# copy.sh 実行後
|- copy.sh
|- aaa.txt
|- aaa_new.txt
|- bbb.txt
|- bbb_bew.txt
```

# script

```bash:copy.sh
#!/bin/bash

DIR=/sample/

# sample.shのディレクトリに移動する
cd $(dirname ${0})

# txtファイルの名前を取得してループ
for pathfile in $DIR/*.txt; do
    # 拡張子を取り除いた名称を取得(Ex. aaa.txt -> aaa)
    NAME=$(basename $pathfile | sed -e 's/\.txt$//g')
    # catからdogに置換して、ファイル末尾に_newを付けてを新規保存する
    sed -e "s/cat/dog/g" pathfile > "${NAME}_new.txt"
done

```
railsで複数の項目から絞り込み検索を実装する際に、collection_check_boxesの引数の書き方で困ったこと

railsで検索機能を実装する際に、collection_check_boxesを使用した。
**投稿(post)にcategory(種類:kind,場所:place)**を設け一覧画面から検索できるように実装した。
今回は複数の項目から絞り込み検索機能を実装する。
初めてチェックボックスを使用するのでググりながら実装してみた結果が以下である。

```ruby
<%= form_for @post do |f| %>
  <div class="form-group">
      <%= f.collection_check_boxes(:category_ids, category.all, :id, :kind) do |ki| %>
      <div class="form-check">
         <%= ki.label class: 'form-check-label' do %>
           <%= ki.check_box class: 'form-check_input' %>
           <%= ki.text %>
         <% end %>
       </div>
     <% end %>
  </div>
  <div class="form-group">
      <%= f.collection_check_boxes(:category_ids, Category.all, :id, :place) do |pl| %>
      <div class="form-check">
         <%= pl.label class: 'form-check-label' do %>
           <%= pl.check_box class: 'form-check_input' %>
           <%= pl.text %>
         <% end %>
       </div>
     <% end %>
  </div>
<% end %>
```
チェックボックスの引数にcategory.allとした結果、作成したいチェックボックスがcategory(種類:kind,場所:place)の両方を合わせた数表示された。
コントローラーを修正しインスタンス変数を使用することにした。それが以下である。

```ruby
posts_controller

def new
  @post = Post.new
  @kinds = Category.all[0..7]
  @placs = Category.all[8..54]
end

private 
  def post_params
    params.require(:post).permit(:image, :name, :content, kind_ids: [], place_ids: [])
  end
```

種類、場所それぞれに配列で欲しい数のチェックボックスが表示されるように範囲を指定した。それに伴いviewファイルも変更した結果が以下である。

```ruby
<%= form_for @post do |f| %>
  <div class="form-group">
      <%= f.collection_check_boxes(:category_ids, @kinds, :id, :kind) do |ki| %>
      <div class="form-check">
         <%= ki.label class: 'form-check-label' do %>
           <%= ki.check_box class: 'form-check_input' %>
           <%= ki.text %>
         <% end %>
       </div>
     <% end %>
  </div>
  <div class="form-group">
      <%= f.collection_check_boxes(:category_ids, @place, :id, :place) do |pl| %>
      <div class="form-check">
         <%= pl.label class: 'form-check-label' do %>
           <%= pl.check_box class: 'form-check_input' %>
           <%= pl.text %>
         <% end %>
       </div>
     <% end %>
  </div>
<% end %>
```
変更の結果、意図した通りチェックボックスが任意の数表示さすことができた！
Failed to create bus connection: No such file or directoryとなった時の対応方法


- 環境 : Dockerで作ったコンテナのCentOS Linux release 7.8.2003 (Core)

# コンテナでロケールを設定しようとしたら怒られた

```bash
# 日本時間に設定したかった
$ date
Mon Jun 15 01:32:49 UTC 2020

$ timedatectl
Failed to create bus connection: No such file or directory
$ localectl status
Failed to create bus connection: No such file or directory
```

# 原因 : ディストリビューションの設定コマンドは使えないから

> CentOS7のロケール設定コマンドである localectl はコンテナ上で実行できません。
> systemctlなどと同様にエラーになります。
> [Dockerfileで日本語ロケールを設定する方法。およびロケールエラーの回避方法。 - Qiita](https://qiita.com/YuukiMiyoshi/items/f389ea366060537b5cd9)

## 環境変数を設定する
注意 : 操作はすべてroot権限で実行する

```bash
# 1. 日本語のロケールを追加する
$ localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
$ locale -a
C
POSIX
en_US.utf8
ja_JP.utf8

# 2. 全ユーザーに適用するように/etc/profileに環境変数を設定する
$ vi /etc/profile
$ cat /etc/profile | grep -e LANG -e LC
LANG="ja_JP.UTF-8"
LANGUAGE="ja_JP:ja"
LC_ALL="ja_JP.UTF-8"

# 3. 反映する
$ source /etc/profile
$ date
Mon Jun 15 11:24:15 JST 2020
```

### Dockerfileで設定する場合
出典 : [Dockerfileで日本語ロケールを設定する方法。およびロケールエラーの回避方法。 - Qiita](https://qiita.com/YuukiMiyoshi/items/f389ea366060537b5cd9)

```text
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"
```
Sessionはブラウザを閉じると消去されるように設計されたCookieであり、それをやり取りするメソッドだった: Railsチュートリアル備忘録 - RailsのSessionとは?

# Sessionはブラウザを閉じると消去されるように設計されたCookieであり、それをやり取りするメソッドだった: Railsチュートリアル備忘録 - RailsのSessionとは?

## Abstract: RailsのSessionとは

Progateのころから気づけば隣にいた`session`

Railsチュートリアルを進めていくと

セッションとかいう変数みたいなものと
それを補足するCookieを利用したログイン維持の仕組み
というモヤモヤした感じを抱いていたが実際は

どちらも

- HTMLをステートフルにするための仕組み
- デフォルトではどちらもCookieに保存される

ただし

- sessionはRailsが実装してくれていたのに対して, Cookieによるログイン維持は後から実装した
- sessionは期限あり（デフォルト?）に対して, 後者は永続的（意図的に設計した）

期限付きCookieを利用した
セッションというHTMLをステートフル化するための仕組みを
**開発者が意図することなく**実装してくれていたのがRailにおけるsessionメソッドということかと



## 備忘録: RailsのSessionとは

### 本来HTMLはステートレスであり、連続性保続性がない

一瞬でわかるステートレス
[DIVE INTO CODE | ログイン情報保持について学ぼう](https://diveintocode.jp/blogs/Technology/SessionManagement)



### SessionはステートレスなHTMLを、ステートフルにするための仕組み

そっか、Cookie**みたいな**仕組みか
Railsチュートリアルの 8章でやりました

と思ったら、
そもそもRailsはデフォルトでsessionをCookieに保存しているとのこと

Chromeのデベロッパーツールで確認してみたところ
Railsチュートリアルのsample_app用と思われる`_sample_app_session`があります

さらにその有効期限は**”ブラウザ セッションの終了時”**となっており
Railsチュートリアルで刷り込まれた儚い感じの所以はこれでした



### Railsにおける`session`は？

`session`は変数ではなくメソッドとのこと
`rails new sample_app`のプロセスで自動的に生成されていたので

**ものすごく当たり前のように使えていた**と理解した

> たとえば、Rails がインストールされた状態でrails new hogeすると Rails アプリケーションができあがって、hogeディレクトリ内でrails g controller sessionsすると ApplicationController を継承した SessionsController が生成されますが、はじめからsession[:hoge]といった書き方で session を利用することができます。[Rails の session を完全に理解した - Qiita](https://qiita.com/zettaittenani/items/a75f0da8f44cfe0f85c0)

もう少し簡単にRailsのsessionの実態を理解するのにこちらを参考にしました
[【Rails】Sessionの使い方について - Qiita](https://qiita.com/ozackiee/items/4ee774c81b2a0c571c05)
【Hosted Graphite】Graphiteを進化させてしまった監視ツール

Graphiteとは、2008年にリリースされたオープンソースの時系列系データの監視プラットフォームです。このツールを使えば、時系列データを取得して、そのメトリクスを収集し、記録して視覚化出来るため、インフラ監視のためによく使われています。

MetricFireでは、ただのGraphiteを進化させたHosted Graphiteを提供しています。普通のGraphiteのサービス開始当初は画期的なサービスであったにもかかわらず、モニタリングのニーズの変化に常に追いついていませんでした。そこで、Hosted Graphiteは、現在のエンジニアが直面している現実の状況に対応するために一から構築されました。それ以来、MetricFireのSREチームはこれらの変化に対応するために拡張と改善を続けてきました。

ここでは、普通のGraphiteでは苦戦しているところ、Hosted Graphiteがそれを改善している点をいくつかご紹介したいと思います。

#StatsDの代わりにData Viewsを使用する
Graphiteの入門書のほとんどが、アプリケーションのメトリクスを送信するためにStatsDを使用するように説明しています。StatsDは事前集計サービスであり、普通のGraphiteの制限により必要になってきます。具体的にはGraphiteのWhisperデータベースはタイムスタンプごとに1つのデータポイントしか受け付けることができません。StatsDは、10秒ごとにデータポイントを収集し、受信した値から新しいメトリクスを作成することでこれに対処します。

これは、複雑さと潜在的な失敗のポイントを追加することになりました。また、複数のStatsDサーバーを運用している場合、各メトリックのデータポイントがすべて同じインスタンスに送信されることを確認する必要があり、基本的なStatsDサーバーにはマルチスレッド機能がないため、負荷がかかる可能性があるため、スケーリングの妨げにもなります。

Hosted GraphiteはData Viewsを使用して自動的にデータポイントの集計を行います。Data Viewsは新しいユーザーがすぐに始められるようにし、アプリケーションの監視に加えてStatsDを扱う手間を省くことができます。Hosted Graphiteが受け取る全てのメトリックは9つ以上の異なるデータビューとして保存され、いつでもビューを切り替えることができます。必要なのは、メトリックのサフィックスを変更するだけです。

#容易なスケーリングのためのネイティブクラスター
Hosted GraphiteがGraphiteのWhisperストレージを上回るもう一つの利点は、クラスターベースであるためスケーリングが容易で、毎分何百万ものデータポイントを取り込むことができることです。

Whisperは各メトリクスの解像度ごとに1つのファイルを使用しているため、準備なしで新しいメトリクスを作成することができます - これはGraphiteが開発当初に導入した大きな進歩でした。残念なことに、現代のクラウドやコンテナベースのサービスの監視では、メトリクスは高頻度で頻度が低い傾向にあります。Whisperのファイルベースモデルは、このような負荷がかかると苦戦します。

一方、Hosted Graphiteは大規模なクラスターベースの非リレーショナルデータベースを中心に構築されており、Whisperの全ファイルシステムとは異なり、受信したデータポイントのみを保存します。データポイントは必要なときにのみ保存・取得され、読み込みよりも書き込みが優先されます。

#9つのビュー、9倍の価値
この全体のセットアップの利点の1つは、メトリックの制限が最初に表示されるよりも多くの値を与えてくれることです。標準の Graphite では、タイマーメトリクスの平均、最小、最大、95パーセンタイルの４種類を見たい場合、4つのStatsDメトリクスを保存する必要があります。しかし、Hosted Graphiteでは、これらのすべてのビューを自動的に利用することができます。Hosted Graphiteでは、標準のGraphiteの4つのメトリックではなく、1つのメトリックで同じ情報を見ることができ、パーセンタイル値をその場で選択することができます。

Hosted Graphite を使用すると、StatsDを必要とせずに直接メトリクスを送信できるシンプルさ、クラスタベースのモデルの信頼性とスピード、そして、受信したメトリクスごとに 9 つのメトリクスに相当するメトリクスを保存することで、ユーザーはより多くの利益を得ることができるのです。
AWS Amplifyを使って、ReactをCI/CDする

Reactつかってチーム開発することになったんだけど、いちいちテストしたりするのはさすがに面倒だし、ヒューマンエラーの原因にもなりかねないので、なんかないかなーと思って調べてみたらAWS Amplifyを見っけた。
やってみたらめちゃんこ簡単だったのでお勧めしてみる。
[公式チュートリアル](https://aws.amazon.com/jp/getting-started/hands-on/deploy-react-app-cicd-amplify/)

# 必用そうなもの
- node環境
- AWSアカウント
- git hub(ほかにも種類があるのでいずれか一つ)

nodeの環境とかはもうあるものだと思って進めちゃいます。

# Reactアプリを作る
とりあえず適当なアプリを作っちゃいましょう

```console
npx create-react-app testapp 
```

ちゃんと作れたか念のため確認しておいたほうがいいかもしれないですね

```console
cd testapp
npm run start
```

# gitにあげる
gitにリポジトリを作って、コードをpushしましょう。

```console
git init
git remote add origin git@github.com:[username]/[repositoryname].git
git add .
git commit -m ‘first commit’
git push origin master
```

# Amplifyの設定をする
設定もめちゃ簡単。
Amplifyのページから、Deployの下のほうのGTE STARTDEを選択する。
git hubを選択して、さっきつくったリポジトリを選択して、ブランチを指定する。(デプロイしたいブランチを指定するべきかな)
次に移動するとビルド設定が出てくるけどスルー。
保存してデプロイするとデプロイが開始。少し時間がかかるけど終了すると、サムネが表示される。
URLをクリックすると表示の確認もできる。

# テストは?
テストについては、ビルドの時点で実行されてるみたい。
Reactアプリ作成時に、App.test.jsみたいなのが作られてると思うけど、それを実行してくれてるみたい。
BuildとDeployの間にTestって項目があって、そこで確認できるよ。

# まとめ
Amplify使ったら、gitにpushするだけでテストの実行からデプロイまで自動でしてくれるみたい。
設定とか操作自体も簡単なのでぜひつかってみるとよいかも！
【Swift】Alamofire 5.2.1でModule 'Alamofire' has no member named 'request'と出る場合の対処法

PodFileに`pod 'Alertift'`と指定し、最新版`5.2.1`を利用。

```Swift
import UIKit
import Alamofire

class NetworkManagerEX: NSObject {

    func sendRequest(success: @escaping () -> Void) {
        let dic: Parameters = [
            "name1":"data1",
            "name2":"data2"
        ]
        Alamofire.request("http://localhost:8000/",
                          method: .post,
                          parameters: dic,
                          encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    print("VALUE:",value)
                    success()
                case .failure(let error):
                    print("RESPONSE ERROR：", error)
                }
        }
    }
}
```

上記内容で`Module 'Alamofire' has no member named 'request'`と怒られたので下記のように修正する事で回避しました。


```Swift
    func sendRequest(success: @escaping () -> Void) {
        let dic: Parameters = [
            "name1":"data1",
            "name2":"data2"
        ]
        AF.request("http://localhost:8000/",
                          method: .post,
                          parameters: dic,
                          encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    print("VALUE:",value)
                    success()
                case .failure(let error):
                    print("RESPONSE ERROR：", error)
                }
        }
    }
```

###参考
[StackOverView](https://stackoverflow.com/questions/28549832/module-alamofire-has-no-member-named-request)
Angularのルーティングで子画面間の遷移時にデータが更新されなくて困ったお話し

Angularでのお話し。
先日、登録画面で確定ボタンを押下した後に、自動的に詳細画面へ遷移する仕組みを実装しました。
実装内容としましては、そのまんま、登録API呼んで、レスポンスの詳細IDとか受け取って、詳細画面へ　````router.navigate```` させる。
登録画面では特に問題なし！

ところが、登録画面があるならもちろん編集画面もあり、編集画面にも同じ機能を実装。

編集完了ボタンを押下後、詳細画面へは遷移するも、更新前の情報しか反映されない。。。なぜ？？

API呼んでsubscribeしてから遷移しているのに、どうしても、更新されていないまま、詳細画面へ遷移する。。。

え～～～～～、なんで～～～～(涙)

意地になってsetTimeout とか試してみたりしても結果は変わらず（涙汗）
errorとかも、まったく全然出ていない。

いろいろ調べた結果、編集画面と詳細画面の両者ともにroutesの設定で、childrenの同階層に設定されており、その場合どちらか一方からどちらかへ遷移するのに大元のパスまたはパスパラメータが、変更されないのでガードとリゾルバーが再実行されないようです。。。

対応策としましては、routeでガードとリゾルバがいつ実行されるかを定義する「runGuardsAndResolvers」というオプションがあるので、これに「'always'」を設定してやるとガードとリゾルバーはURLへの変更の度に起動されるようになるそうな。

```
export const ROUTES: any = [
  {
    path: 'hogehoge/:name',
    runGuardsAndResolvers: "always",
    component: HogejectComponent,
    resolve: { hoge: HogeResolver },
    children: [
```

おぉ～～～！ちゃんと更新されている～～～！解決！！

###参考にさせていただいた記事
[https://stackoverflow.com/questions/44232418/how-to-refresh-a-routes-resolved-data](https://stackoverflow.com/questions/44232418/how-to-refresh-a-routes-resolved-data)
[https://juristr.com/blog/2019/01/Explore-Angular-Routers-runGuardsAndResolvers/](https://juristr.com/blog/2019/01/Explore-Angular-Routers-runGuardsAndResolvers/)
ERROR: No such service:となった時の対応方法


- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - Docker Engine Version:19.03.8
    - docker-compose version 1.25.5

# 事象 : `docker-compose`コマンドを使ったら怒られた

```bash
$ docker ps
CONTAINER ID    IMAGE       COMMAND            CREATED             STATUS        PORTS                     NAMES
1f8c9d969c7a    ponsuke_app "/usr/sbin/init"   53 minutes ago      Up 53 minutes 0.0.0.0:8081->8080/tcp    app-v2.0.0.0

$ docker-compose restart app-v2.0.0.0
ERROR: No such service: app-v2.0.0.0
```

# 原因 : 指定しているのがサービス名じゃなくてコンテナ名だから
いつもサービス名とコンテナ名を一緒にしていたが、たまたま変えたら引っかかった。

```yml:docker-compose.yml
version: '3.8'
services:
  app:    # << サービス名
    container_name: app-v2.0.0.0 # << コンテナ名
...省略...
```

> Usage: restart [options] [SERVICE...]
> [docker-compose restart | Docker Documentation](https://docs.docker.com/compose/reference/restart/)

## 対応 : サービス名を指定して`docker-compose`を使う
```bash
$ docker-compose restart app
Restarting app-v2.0.0.0 ... done
```
Zabbix 特定ユーザの指定アプリ(プロセス)のメモリ使用量を監視したい


 * 普段使うアイテムはこちら

```bash
perf_counter["\Process(explorer)\Working Set"]
```

#新規アイテム
 * 例）ユーザ：app_user、アプリ：explorer(.exe)

 * まず、cmdでテスト

```bash
tasklist /fi "USERNAME eq app_user" /fi "IMAGENAME eq explorer.exe"
```
~~@echo off & for /f "tokens=5 skip=3" %i in ('tasklist /fi "USERNAME eq app_user" /fi "IMAGENAME eq explorer.exe"') do set line=%i & echo %line:,=% & exit /B 0~~


できるだけPowerShellにしたい

 * アイテム
  * タイプ: Zabbixエージェント(アクティブ)
  * データ型: 数値 (整数)
  * 単位: B
  * キー

```PowerShell
system.run[PowerShell "(Get-Process -Name explorer -IncludeUserName | Where-Object { @('app_user') -contains $_.UserName }).WS"]

or

system.run[PowerShell "(Get-Process -Name explorer -IncludeUserName | ? { @('app_user') -contains $_.UserName }).WS"]

```

# 参考
 * https://docs.microsoft.com/ja-jp/powershell/scripting/samples/selecting-parts-of-objects--select-object-?view=powershell-7
 * [PowerShellでプロセスを実行しているユーザーを調べる方法](https://win.just4fun.biz/?PowerShell/%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%8B%E6%96%B9%E6%B3%95)
APIを提供するALBでメンテナンスモード(503)を実現する(CORSに対応する)

# APIを提供するALBでメンテナンスモード(503)を実現する(CORSに対応する)
この記事は

- APIをALBを使って解決している
- SPAとAPIのエンドポイントが違う（クロスオリジン）
- SPA側でメンテナンスレスポンスをハンドルしている

という状況での解決方法になります。
## はじめに

AWSのALBには固定レスポンスという機能があり、特定のステータスコードとbodyを固定で返却する事ができます。
コレを設定することで、アプリケーションがメンテナンスモードの時などに固定でメンテナンス画面を表示することが出来ます。

[固定レスポンスの設定方法](https://dev.classmethod.jp/articles/alb-fixed-response/)

ところが、SAP+APIのような構成のアプリケーションを使用している際、API側のALBで固定レスポンスを設定するとある問題が発生します。

**SPA+APIモデルのアプリケーションで固定レスポンスが出来ない**

ALBの固定レスポンスではメンテナンス中という旨のJSONを返却できます。しかし、以下のようにステータスコード、コンテンツタイプ、本文しか返却内容に設定することが出来ません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/2c88ddea-7532-c864-d74b-1fe9739e1b43.png)

元々APIとSPAのエンドポイントが違うアプリケーションの場合、アプリケーション側でCORSの対応をしていることが多々あると思われますが、ここでの固定レスポンスにCORS対応のヘッダーを含めることが出来ずSPA側でCORSのエラーが出てしまいます。

## Lambdaを使って解決する

固定レスポンスでヘッダーの設定は無理そうなので、ALBからLambdaをターゲット指定し、そこでCORSヘッダー込みの503をレスポンスします。

### 1.とりあえずLambdaで関数を作ります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/ef85e85c-2110-6fd4-f527-39318acd3d56.png)


（ランタイムは好きなので良いですが、僕がフロントエンドエンジニアなので今回はNodeです）

### 2.関数を書きます。

pre-flightリクエスト時にも503を返すと面倒なのでpre-flightのときは204を返します。設定したいヘッダーを盛りに盛りましょう。

```javascript

exports.handler = async (event) => {
  if(event.httpMethod === 'OPTIONS') {
    const response = {
      statusCode: 204,
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': '*',
        'Access-Control-Allow-Credentials': 'true'
      },
      body: '',
    };
    return response;
  }
  const response = {
    statusCode: 503,
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*',
      'Access-Control-Allow-Credentials': 'true'
    },
    body: JSON.stringify({"message": "（サンプル）ただいまメンテナンス中です。ご迷惑をおかけいたしますが、よろしくおねがいいたします。メンテナンス期間：2020-7-1 19:00〜 2020-07-1 21:00"}),
  };
  return response;
};
```

保存します

### 3.ターゲットグループの作成

ALBから呼び出すために、Lambdaを起動するターゲットグループを作成します。

AWSのメニューからEC2を選択し、ロードバランシングのターゲットグループに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/e82c082f-a509-df30-9254-c19800df67ad.png)

ターゲットグループを新規作成します
いい感じの名前をつけてさっきの関数を選択します。ついでにヘルスチェックも有効にしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/a4140b57-fdfb-d8b2-92f6-5c363a4df63c.png)

作成したらALBにこのターゲットを設定します。

### 4.ALBにターゲットを設定する

ロードバランサーから、目的のロードバランサーを選択肢、リスナー＞ルールの編集へアクセスします。

現状適用されているルールの一覧が出るので、ここに新規で作成します。

明らかに追加できそうなボタンがあるのでコレを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/4861de36-84e1-15be-70e9-f60f0ebc95fb.png)

任意の場所にルールを挿入したら以下のように設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/12dfa660-61a6-f9e7-f92b-538868bc7efb.png)


今回はメンテナンスモードを想定しているのですべてのリクエストでこちらに反応するようにしています。

**これで設定が完了です。このルールがトップのときはいかなるリクエストにも503をCORS付きで返却します。**

## あとがき

API Gateway...
読書要点「プリンシプルオブプログラミング」第3章 プログラミングセオリー

# 第3章 思想

プログラミングを支えてきた思想である。
今まで多くのソフトウェアの成功を支えてきた思想を、身近に活かすことのできる場面は少なくない。

## プログラミングセオリー

プログラミング最大の関心事は最高のコードを作り上げることである。
最高のコードとは、拡張しやすく、余計なものがない、読解しやすいコードである。
最高のコードを実現するためのセオリーがプログラミングにはある。

セオリーを支える根幹の価値は3つある。
それはコミュニケーション、シンプル、柔軟性である。
また、この抽象的な価値を実務に適用していくための原則が6つ存在している。
結果の局所化、対称性、繰り返しの最小化、宣言型の表現、ロジックとデータの一体化、変更頻度である。

以降、この価値と原則について個別に説明していく。

###価値：コミュニケーション

コードは人が読むドキュメントであり、コミュニケーションツールの一つであると言える。
コードを書く時間以上に読む時間が長くなる開発の中で、円滑なコミュニケーションを行うために読みやすいコードを書くことはとても重要である。
書いているときほど読み手側の視点に立って考えるべきである。

###価値：シンプル

ここでいうシンプルとは、コードに含まれる余分な複雑性を排除した状態のことである。
要件を満たすために必要な複雑性ではなく、過剰な遠回りをしているような複雑性のことである。
読み手側は読むコードが簡潔なほど理解に要する時間は短くなり、保守も行いやすくなる。

まれにシンプルとコミュニケーションが競合する場合があるが、その場合はコミュニケーションを優先するべきである。
長期的に読まれていくことを考えると、読み手と円滑なコミュニケーションを行うことのほうが優先度が高い。

###価値：柔軟性

ここで言う柔軟性とは、コードの変更が容易であるということだ。
いずれコードが変更され、長期的に保守が行われることを考えるとコードは柔軟性を持っているに越したことはない。

ただし、柔軟性を理由にコードが複雑性を持つことを正当化されがちである。
ここで、現在必要ではないものは書かないYAGNIという原則を思い出したい。
今必要のないものは結果として複雑性を増すのみだという認識を持ち、真に保守性の高いコードを書くことを心がけたい。

###原則：結果の局所化

ここでいう結果とは、コードを変更したときの影響のことを言う。
結果の局所化とは、変更の影響が局所的に留まるようにすべきだという原則である。
モジュール化やMVCモデルをはじめ多くの技術が、結果の局所化の実現を目指して生み出された。

結果が局所化されているほど、保守の際のコストが減るうえ、局所化がされているという共通認識があればコミュニケーションのコストも抑えることができる。

関係が濃密なコードをひとまとめにして、過剰に分散させないことが重要だ。

###原則：繰り返しの最小化

ここでいう繰り返しとは重複のことであり、重複はできるだけ減らしたほうが良いという原則である。
関数化のような技術は繰り返しの最小化を動機としている。
コピペを複数ヶ所に含むコードは結果の局所化の減速を侵害しており、変更コストが大きい。
また、似たような記述から変更すべきか否かを判断することになり、読むコストも増える。

同じ記述を減らすためにもコードを小さい単位に分割して管理するのが良い。
分割していく過程でコードが持つ共通項の把握も進む。

###原則：ロジックとデータの一体化

処理と処理で扱うデータをなるべく近くに配置すべきだという原則である。
コードの修正する時、処理とデータを変更するタイミングはだいたい同じである。
変更するタイミングが同じものは近くにあったほうが読むコストが減るうえに、結果の局所化にもつながる。

###原則：対称性

コードの中のグループにおいて、同じ種類のものを同じレベルで表現すべきだという原則である。
コードの対称性は可読性を引き上げる。
一部を読むだけでグループが持つ性質、グループの他の部分への類推が可能になる。


###原則：宣言型の表現

宣言型の表現と命令型の表現の2種類がある。
宣言型では問題の定義を記述し、命令型では問題の解法を記述する。
宣言型では順序や条件分岐がなく論理的な流れは存在しないためコードを読みやすい。

積極的に宣言型のコードを取り入れ、読みやすいコードを作るのが良い。
命令型のプログラミング言語でも宣言型の記法が用意されていたり、宣言型の考えを取り入れたフレームワークがあるため、宣言型の言語と合わせて取り入れていきたい。

###原則：変更頻度

コードのグルーピングの際に、コードの変更頻度で分類すると良いということである。

「対称性」では同種のものをグループ化することを推奨したが、こちらでは時間軸的に考えてグループ化を行う。
同じタイミングで変更するコードをまとめておけば、コードの修正範囲は狭くなり、結果の局所化につながる。
また、そもそも変更頻度が同じものは変更の理由も同じことが多い。

モジュールを作るときは、モジュールが持つ責任は一つより多くあってはいけないという単一責任の減速を意識しておくと、変更頻度の原則の達成につながる。
テスト投稿

Login
https://access.line.me/oauth2/v2.1/login?loginState=201kOlQnjS7Xifvj9T8glN&loginChannelId=1446101138&returnUri=%2Foauth2%2Fv2.1%2Fauthorize%2Fconsent%3Fscope%3Dopenid%2Bprofile%2Bfriends%2Bgroups%2Btimeline.post%2Bmessage.write%26response_type%3Dcode%26redirect_uri%3Dhttps%253A%252F%252Fsocial-plugins.line.me%252Flineit%252FloginCallback%253FreturnUrl%253Dhttps%25253A%25252F%25252Fsocial-plugins.line.me%25252Flineit%25252Fshare%25253Furl%25253Dhttp%2525253A%2525252F%2525252F198.13.57.83%2525253A5858%2525252F%26state%3D0328299d0c311cf79afe1720db1039%26client_id%3D1446101138#/


#	Result	Protocol	Host	URL	Body	Caching	Content-Type	Process	Comments	Custom	
1	200	HTTP	Tunnel to	torimochi.line-apps.com:443	0			microsoftedgecp:2076			
2	200	HTTP	Tunnel to	social-plugins.line.me:443	0			microsoftedgecp:2604			
3	200	HTTP	Tunnel to	social-plugins.line.me:443	0			microsoftedgecp:2604			
4	200	HTTP	Tunnel to	access.line.me:443	0			microsoftedgecp:2604			
5	200	HTTP	Tunnel to	torimochi.line-apps.com:443	0			microsoftedgecp:2604			
6	200	HTTP	Tunnel to	optout-api.tr.line.me:443	0			microsoftedgecp:2604			
7	200	HTTP	Tunnel to	vortex.data.microsoft.com:443	0			backgrounddownload:1180			
8	200	HTTP	Tunnel to	ssl.gstatic.com:443	0			chrome:10448			
9	200	HTTP	Tunnel to	torimochi.line-apps.com:443	0			microsoftedgecp:2604			
10	200	HTTP	Tunnel to	torimochi.line-apps.com:443	0			microsoftedgecp:2604			
11	200	HTTP	Tunnel to	access.line.me:443	0			microsoftedgecp:2604			
12	200	HTTP	Tunnel to	clients4.google.com:443	0			chrome:10448			
13	200	HTTP	Tunnel to	access.line.me:443	0			microsoftedgecp:2604			
14	200	HTTP	Tunnel to	social-plugins.line.me:443	0			microsoftedgecp:2604			
15	200	HTTP	Tunnel to	torimochi.line-apps.com:443	0			microsoftedgecp:2604			
16	200	HTTP	Tunnel to	social-plugins.line.me:443	0			microsoftedgecp:2604
RxSwift Training②

# NumbersViewController

## ① 足し算の箇所を掛け算にする
- StroyBoardの修正は不要
- result（UILLabel）に表示される内容を掛け算にする


# SimpleValidationViewController
## ② Buttonタップ時に表示されるアラートのタイトルとメッセージを変更
- タイトル： Usernameのformの値
- Message: Passwordのformの値

## share(replay: scope:)
下記を参考に
https://medium.com/gett-engineering/rxswift-share-ing-is-caring-341557714a2d

## ③ share(replay: 1) -> share()に変えたらどうなるか？


# GitHubSignupViewController1
## ④ usernameValidationOutletに表示される `validating` テキストと色を変更する
- テキスト： `validating ...` -> `確認中 ...`
- カラー：  `UIColor.black` -> `UIColor.gray` 

## ⑤　usernameOutletに入力をしたときに表示される `validationg...` を表示しないようにする
- VCのロジックはいじらない。VMからvalidationgが返らないようにする

## ⑥ 考え中
【R】ワードクラウドの画像を保存する

微妙に面倒だったのでメモ。
ワードクラウドの作り方は割愛。
使用パッケージはwordcloud2です。


#環境
windows10
R 4.0.1

#パッケージとかの追加

```R
install.packages("webshot" , lib="./library")
install.packages("htmlwidgets" , lib="./library")
```
Rにコマンド上で上記のパッケージを落とします。
「webshot」がスクリーンショット保存してくれる人なのですが、なんとこいつ「PhantomJS」とかいうブツがないと働いてくれません。
ので入れます。

https://phantomjs.org/download.html
上記サイトのダウンロードからぽちっとzipを落として適当な場所に保存。
今回はRと運命を共にしてもらうために同階層に置きました。

そして環境変数の設定。

```
C:\Program Files\R\phantomjs-2.1.1-windows\bin
```

コマンドプロンプトでパスが通っていることを確認します。


#画像の保存処理
丸パクリとも言うブツです。

```R
library(wordcloud2)
library(webshot)
library(htmlwidgets)

my_graph <- wordcloud2(hoge) #処理は省略
saveWidget(my_graph, "tmp.html", selfcontained = F)
webshot("tmp.html", "wordcloud.png", delay = 60, vwidth = 800, vheight = 800)
```

これを実行すればあら不思議スクリーンショットが保存されました！
別に不思議じゃないですけどね。
delayが60なのはワードクラウドがある程度描画されるまで待ちたかったからなのですが、そこまで待たなくてもよさそうです。

これで毎回手動でスクリーンショットを撮らなくて良くなりました。ヤッタネ。


#参考
https://ja.coder.work/so/r/2950868
https://kazutan.github.io/kazutanR/webshot_demo.html
HTML Works - テンプレートエンジンを利用できる静的HTML作成環境(ツール)を作ってみた

# 開発の背景
マニュアルページを作成しようとした際に、サイドメニュー部など同じ要素を毎ページ記述するのが無駄だなと。(最近はフレーム分割などせずに単一ページにメニュー部をもつデザインが多い)
プログラム込みのWebページ開発であれば、フレームワーク(例えばPythonのDjangoなど)にテンプレートエンジンが大抵用意されていますので、共通部の部品化など効率的な開発が可能です。
このテンプレートエンジンを利用した開発を純粋なHTMLの作成でもできないかなと思ったのが発端です。
ひとまず既存のツールを探してみたところ、[HUGO](https://gohugo.io/)というツールがヒットしたのですが、コンテンツ部分はMarkdownで記述するタイプらしくちょっと自分のニーズとは違いました。
というわけで自作しよう！と(笑)

# テンプレートエンジンを利用できる静的HTML作成環境(ツール)
そしてひとまず必要最低限の機能を実装し、まだまだ趣味の範囲ではありますが動くものになったので、下記GitHubで公開してみました。
[HTML Works](https://github.com/playree/htmlworks)

最近はもっぱらPythonを好んで使っていますが、ツールとして配布を考えると実行形式にビルドできるほうが良いかと思い`Go言語`を採用しました。
テンプレートエンジンや簡易サーバー機能を標準で備えているのも`Go言語`を採用したポイントです。
ソースも一緒に公開していますので、興味のある方はどうぞ。
ただしGo言語熟練者というわけではないので、おかしいソースがあるかもしれませんが、そのへんはご容赦ください。

# HTML Works の主な特徴
* HTMLのテンプレートエンジンを使用できる  
テンプレートエンジンには、Go言語の `html/template` を採用しています。(というかそのままですｗ)  
テンプレート記述のみで完結できるよう、テンプレートエンジンを多少拡張しています。
* WEBサイト公開用の静的HTMLを生成できる  
テンプレートエンジンを使用した記述方法で作成したコンテンツから、公開用の静的HTMLを作成します。  
本ツールの主機能になります。
* 開発用の簡易サーバーを使用して静的HTML生成前にコンテンツを確認できる  
開発用の簡易サーバー機能を用意していますので、編集中のコンテンツをリアルタイムで確認できます。
* Windows/Mac/Linuxの各種環境で使用可能  
Go言語で作成していますので、ビルドさえ行えば各種環境で使用可能です。  
バイナリ(実行形式)での提供は徐々に増やす予定です。

# 使い方
基本的な使い方は[README](https://github.com/playree/htmlworks)を参照ください。

下記に開発の一例を紹介します。

```html:contents/index.html
<!--params
{
    "title":"HTML Works",
    "str1":"abc",
    "int1":123,
    "bool1":true,
    "array1":["a1","a2","a3"]
}
-->
{{extends "_parts/base.html"}}
{{define "content"}}
    <p>str1:{{.str1}}</p>
    <p>int1:{{.int1}}</p>
    <p>
    bool1:{{.bool1}}
    {{if .bool1}}
        <p>if TRUE</p>
    {{end}}
    </p>
    <p>
    array1:
    <ul>
        {{range $i, $val := .array1}}
        <li>{{$i}} : {{$val}}</li>
        {{end}}
    </ul>
    </p>
{{end}}
```

```html:contents/_parts/base.html
<html>
<head>
    <title>{{.title}}</title>
    <link rel="stylesheet" href="/resources/css/kuroutokit.css" />
</head>
<body>
    {{template "content" .}}
</body>
</html>
```

上記２ファイルを用意して`HTML Works`で生成を実行すると、下記ファイルが生成される流れになります。
生成を実行しなくても、開発用サーバーを実行することでブラウザから生成後の内容をリアルタイムで確認もできます。

```html:public/index.html
<html>
<head>
    <title>HTML Works</title>
    <link rel="stylesheet" href="/resources/css/kuroutokit.css" />
</head>
<body>
    <p>str1:abc</p>
    <p>int1:123</p>
    <p>
    bool1:true
        <p>if TRUE</p>
    </p>
    <p>
    array1:
    <ul>
        <li>0 : a1</li>
        <li>1 : a2</li>
        <li>2 : a3</li>
    </ul>
    </p>
</body>
</html>
```

このように`base.html`に共通の内容を記載(他にもサイドメニューを記載したり)することで、共通部の編集が１ファイルで済むような開発が可能となります。
centos8 /usr/local/bin への path 通し方

.bash_profile に書いても、
何故かログアウトや再起動するとパスが有効になっていない。
起動時に source コマンドをするのは面倒。




ということで。
ログインするたびに毎回パスを通しておこう。



```/root/.bashrc

PATH=$PATH:$HOME/bin:/usr/local/bin
export PATH

```

を追記。


で、ログアウト、再度ログイン。
もしくは、サーバーをreboot。


echo $PATH

```
/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/bin

```

`OK`
rails-erdがエラーで使えない！ Graphvizが必要です

# 環境
Vagrant + Ubuntu 16.04.5 LTS
Rails 5.2.4.2

# はじめに

**rails-erd**とは、ER図のPDFファイルを自動作成してくれるgemです。**Gemfile**に**gem 'rails-erd'**を記述して、**bundle install**すると、**rails erd**コマンドでPDFファイルが作成されるようなのだが、エラーが出てきたので、そのトラブルシューティングです。

# 手順

**rails erd**コマンドで、このようなエラーが出てきます。

```
$rails erd
rails aborted!
Unable to find GraphViz's "dot" executable. Please visit https://voormedia.github.io/rails-erd/install.html for installation instructions.
/vagrant/syougai/bin/rails:9:in `<top (required)>'
/vagrant/syougai/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => erd => erd:generate => erd:check_dependencies
(See full trace by running task with --trace)
```

どうも、**Graphviz**というツールをインストールしておかないといけないようです。Graphvizがインストールされていないのか念のために確認する。

```
$apt list --installed | grep grap
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
````

WARNINGが出てきたが、**apt install**はCLIでは利用してもいいが、スクリプト内で利用するには、**apt-get install**の方が推奨されていますという注意喚起のようです。

Graphvizをインストールする。

```
$sudo apt install graphviz
```

**rails erd**を実行する。

```
$rails erd
```

Railsのプロジェクトのルートに、erd.pdfが作成されました。

# 参考URL
https://tech.mof-mof.co.jp/blog/try-rails-erd/
aws technical essentials 2 をオンラインで受けた感想

# aws technical essentials 2 の感想
はい皆さんこんにちは

結論から言うとこの記事は
有料研修（結構高い）の
aws technical essentials 2を受けたので、これから受ける人の参考になればと記事を書いておきます。
・WordPressちょっと触ります
・時間は余裕ないです
・SQLの知識もあったほうが良いが、無くても良い。

# 詳細

資料が欲しい方はこの辺見てください。
https://aws.amazon.com/jp/training/course-descriptions/essentials2/

環境：
こんなご時世ですので、オンラインでの研修でした。

対象サービス：
EC2,RDS,IAM,AMI,snapshot,S3,Wordpress,ELB,AutoScale,CloudWatch,CloudWatch Logs,EBS

##まずはじめに
今回、aws technical essentials 2を受けていますが、
１は受けませんでした。
ある程度業務での前提知識があったのと、会社のお金だったので２だけにしました。

１は、ほとんど手は動かさずに、知識ベースの研修だそうで、
SE以外にも営業の人が受けたりするそうです。

なお、１を受けた人で、SEの人は是非２も受けてくださいと、講師の方がおっしゃってました。

##研修の流れ
※研修用AWSアカウントが払い出されます
①講師の方が15分～20分ほど話します。
②そのあと教材に従ってAWSのコンソールやEC2（SSHログインします）を操作します。
③90分おきぐらいに休憩が入ります
④繰り返し
⑤最後まで終わったら、アンケートを書いて退席します

##オンライン研修をやってみて思った事
・全体へのボイスチャットなので、気軽に質問しづらい・・・と思う人もいるのかな？
・テキストチャットでも質問はできます
・教材は、9割は安心して使えます。逆に言うとたまに変なところや、AWSの画面構成が変わっているので、臨機応変に
・個人的には、教材の文字がやや見辛い。フォントの問題か？
・間違った場合の解決策も教材に載っているので、その辺りは安心。
・講師の方は非常に慣れている感じで、安心して見れました。
・AWS側で障害が起きた場合は、その箇所によって教材をスキップします。
　（実際、私の時に障害があり、ROLEが作れませんでした）


##感想
・あまり時間に余裕は無いです。
　せっせとやるイメージです。
・変わりに教材は9割信用できるのでサクサクです。
・逆に講師の説明が落ち着いていて、眠い。
　（ずっと手を動かしていても疲れるので、いい塩梅なのでしょうね）
・研修が終わってからアンケート書くので、それも時間に余裕が無い感を増長。
・操作に慣れているか、慣れていける人向け。


**ありがとうございました。**
RailsチュートリアルCh5 をAurelia2 で作り直す（ルーティング設定）

# やること

- 各コンポーネントへヘッダー・フッターナビゲーションから遷移できるようにする
- Bootstrapをアプリケーションに追加する

# ToDo
- アプリケーションにルーティング設定を追加する
- ヘッダーナビゲーションにルートを指定する
- フッターナビゲーションにルートを指定する
- ルーティングしたコンテンツのレンダリングをする
- デフォルトでレンダリングするコンポーネントを指定する
- Bootstrapをアプリケーションに追加する

## アプリケーションにルーティング設定を追加する
main.ts ファイルにRouterConfigurationを追加する。

```TypeScript
import Aurelia from 'aurelia';
import { MyApp } from './my-app';
// RouterConfiguration を追加する
import { RouterConfiguration } from 'aurelia';

Aurelia
  // ルーティング設定をアプリケーションに追加する
  .register(RouterConfiguration)
  .app(MyApp)
  .start();
```

## ヘッダーナビゲーションにルートを指定する
aタグ内にgoto="コンポーネント名"を追加することでルートを指定する。

```html
<!---一部省略-->
<nav>
  <ul class="nav navbar-nav navbar-right">
       <li class="nav-item"><a goto="home-page">Home</a></li>
       <li class="nav-item"><a goto="help-page">Help</a></li>
       <li class="nav-item"><a goto="login-page">Log in</a></li>
   </ul>
 </nav>
```
## フッターナビゲーションにルートを指定する
上記のヘッダーと同様にaタグ内にルートを指定する。

## ルーティングしたコンテンツをレンダリングする
my-app.html にルーティングしたコンテンツのレンダリングをするために<au-viewport>タグを追加する

```html
<import from="./shared/header/header-component"></import>
<import from="./pages/home/home-page"></import>
<import from="./pages/about/about-page"></import>
<import from="./pages/content/content-page"></import>
<import from="./pages/help/help-page"></import>
<import from="./pages/login/login-page"></import>
<import from="./pages/news/news-page"></import>
<import from="./shared/footer/footer-component"></import>

<header-component></header-component>
<div class="container>
    <au-viewport></au-viewport>
    <footer-component></footer-component>
</div>
```

## デフォルトのコンポーネントを指定する
この時点で、アプリケーションをnpm startで起動してみるとルートパスにアクセスした際に、ヘッダーとフッター以外のコンテンツがレンダリングされない。期待する動作はルートパスにアクセスした際にもhome-pageのコンテンツがレンダリングされることなので、デフォルトのコンテンツとしてhome-pageを指定する。
先ほど追加した<au-viewport>にデフォルトのコンテンツをしていする。

```html
<!--一部省略-->
<div class="container">
   <au-viewport default="home-page"></au-viewport>
   <footer-component></footer-component>
</div>
```

## Bootstrapをアプリケーションに追加する
Bootstarap をnpm installで追加した上で、my-app.tsにインポートすることで適応する。

```TypeScript
import 'bootstrap/dist/css/bootstrap.css';

export class MyApp {
}
```
# 次にやること
RailsチュートリアルCh6をAurelia2で実装する
npmとは何か勉強した記録

##Macにインストールする

1.https://www.suzu6.net/posts/45/
を参考にまず
homebrewをインストール

2.https://brew.sh/index_ja
ターミナルに上記に書いてあるコマンドをコピペし、エンターキーでインストールを始める
これには数分かかる

3.node.jsを（ターミナルを使わないで）インストールする。
元サイトはこちら
https://nodejs.org/en/download/

4.ターミナルで、npmのバージョンを確認し、出たら成功している。
コマンドは
npm -v



##npmで何がやりたいのか

主にvue.jsなど。
他にも最近じゃあCSSフレームワークなんかもこれでインストールできる。


でもそれ使いたいなら大前提としてnpm使えないと意味が無いんで。

###vue.jsのインストール
https://jp.vuejs.org/v2/guide/installation.html#Vue-Devtools

###npmアンインストール
npm rm パッケージ名
npm r パッケージ名
npm remove パッケージ名
npm uninstall パッケージ名
npm unlink パッケージ名
npm un パッケージ名
プロジェクト内の「良くない」コードを減らすための戦略

# 何をしたいのか

以下のような経験、あるかと思います。

* コンパイル警告を減らしたい
* コード中の古い記法を新しい記法に置き換えたい

小さな個人リポジトリの中であれば気合いと根性で「えいやーっ！」とやれば終わります。
しかし、大きなプロジェクトにおいて気合いと根性でやるのは現実的ではありません。

* そもそも数が多い
* 既存の古い・悪いコードを参考に新しいコードが書かれてしまい同じ問題が増える

これをなんとかしたいんです。

# 3つのことができれば問題は減る

上述のような課題に直面したときは以下の3つを実現する手段を用意するようにしています。

* 減らしたいものを検知する手段を用意する
* 減らしたいものを増やさないようにする
* 減らしたいものを減らす

「ああそんなことか」って感じかもしれません。
しかし、最初の2つはとても大事です。

検知する手段があれば開発者が新しくそういうコードを埋め込んでないか、コミットしたりする前に確認することができます。ちょっと気の利いた人ならば気が向いたときに修正してくれるかもしれません。

また、コミットする前に検知する手段をちゃんと使わない開発者がいたとしても仕組みで問題を増やせないようにしておけば新規で問題のあるコードが書かれて頭を抱えることはないでしょう。増えないのであれば減る一方ですので遠い未来には多分根絶やしにできます。

## 減らしたいものを検知する

Lint やらコンパイルした際に出力される警告やらをそのまま利用すればよいでしょう。ただ、コンパイラの警告だと1年生だとどう読めばいいのか分からない人もいるでしょうからそういった人には別途指導したり、分かりやすく見せるツールを導入したりする必要があります。

そういったツールで検出できない場合は何か用意する必要があります。過去にそういった事例に対処した際には maven のプラグインとして用意するなどして普段の開発サイクルに組み込みやすい方法として用意していました。

## 減らしたいものを増やさないようにする

多くのプロジェクトはきっとバージョン管理ツールを導入していると思います。であれば、その機能で減らしたいものが増えていたらその変更を受け付けないという手段が使えます。
また、コンパイル警告であれば色々な種類があるでしょうから、数ではなくて特定の種類があったら受け付けないというのも一つの手です。減らしたいものを減らす段階でこのやり方の方が合っている場合もあるのでそこと相談しながらやり方を変えるのもありでしょう。

先に用意した検知するツールを上手く実行して問題点の数を確認し、変更前と変更後の数を比較しましょう。結果、増えていたら変更を拒絶します。GitLab を使っているのであれば `.gitlab-ci.yml` を使えば実現可能でしょう。Subversion にも Pre-Commit のフックがあります。各々の環境に合わせて実現していただくのが良いでしょう。

## 減らしたいものを減らす

単純に検知したものを片っ端から消していきます。
ただ、これだけだとちょっと大変なので次のような施策を併せるといいかもしれません。

* 進捗をグラフなどで表示し気分を盛り上げる
* プロジェクトに入った新人向けに「とりあえず流れを確認しよう」みたいな感じで数個減らしてもらう。ただ「これ全部やっておいて」だとモチベーションとか下がりそうなのでチュートリアル程度の数で
* 誰でもやれるように直し方を説明したガイドを用意する

先にも書きましたが、増えないようにしたのであれば後はゆっくりと削っていけば大丈夫です。ただ、制限時間があるようであれば何らかのブーストが必要かもしれません。
Windows 10 + nodejs + selenium-webdriver + chromedriver で headless chrome を試してみる

# 目的
Chromeをnodejs + selenium-webdriver + chromedriverからキックしてみる

## SeleniumBasicのインストール
※環境変数の文字数制限により、同居(笑)
[Seleniumbasic](https://florentbr.github.io/SeleniumBasic/)の Release page より SeleniumBasic-2.0.9.0.exe をDLする
exeを実行すると、C:\Users\user_name\AppData\Local\SeleniumBasic にインストールされる
ソースコードのプロジェクトをVS2019で開くと .NET Framework 3.5 を指定しているので
Windowsの設定 -> アプリ -> オプション機能 -> Windowsのその他の機能 -> .NET Framework 3.5 が有効であることを確認する

## selenium-webdriverのインストール
※v4なのは、Edgeと比較するため(かもしれない)

<pre>
> npm install -S selenium-webdriver
+ selenium-webdriver@4.0.0-alpha.7
</pre>
## ChromeDriverのインストール
[Chrome について](chrome://settings/help)よりChromeのバージョンを確認する

[ChromeDriver - WebDriver for Chrome](http://chromedriver.chromium.org/downloads)よりバージョンに合わせてDLする
chromedriver_win32.zip を解凍後 chromedriver.exe を SeleniumBasic フォルダに上書きする

## サンプルコード

```js
const { Builder, By, Key, until } = require('selenium-webdriver');

let driver;
(async () => {
  try {
    driver = await new Builder().forBrowser('chrome').build();
    
    await driver.get('https://www.google.co.jp/');
    await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
    await driver.wait(until.titleIs('webdriver - Google 検索'), 5000); 
    // await driver.sleep(5000);
  }
  catch(error) {
    console.error(error);
  }
  finally {
    if(driver) {
      await driver.quit();
    }
  }
})();
```
# 参考にしたのは以下のサイト
[selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver)
[Module selenium-webdriver](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/)
[Node.js で selenium-webdriver と chromedriver を使って Chrome ブラウザを自動操作してみる](https://neos21.hatenablog.com/entry/2019/01/14/080000)
[Promiseが分かれば簡単！async, await](https://qiita.com/valley/items/dd37deb77f06eb6c451c)
[Windows 10 + Excel2016 VBA + seleniumbasic で chromedriver / msedgedriver を使ってみる](https://qiita.com/tabizou/items/9793dc04d3d98d3b4842)
美大生のためのプログラミング入門：四角形に関する様々な関数（その 1）

※ Qiita では、本文部分のみの印刷に苦労します。そのため、同じ内容を以下のページにも掲載しています。プリンツアウトしたり PDF 化したい人は、こちらのページを利用して下しさい：

http://gurakura.sakura.ne.jp/hellomondrian/rect2/

一覧はこちら：
http://gurakura.sakura.ne.jp/series/美大生のためのプログラミング入門/

Qiita 版の総合目次：
https://qiita.com/iigura/items/37180d127da93d0b8abb


# 自由な四角形の描き方
　関数 rect で描画される四角形は、水平・垂直の線分にて構成される長方形でした。
しかし、長方形だけが四角形というわけでもなく、四角形という定義にはもっと自由な形の四角形も含まれます。

quad 関数は、このような自由な四角形を描くための関数です。
引数は、quad(x1,y1, x2,y2, x3,y3, x4,y4) であり、それぞれ

	x1,y1: 第 1 頂点の x 座標および y 座標
	x2,y2: 第 2 頂点の x 座標および y 座標
	x3,y3: 第 3 頂点の x 座標および y 座標
	x4,y4: 第 4 頂点の x 座標および y 座標

となります。

　このような表記は少々冗長にも感じますので、以後、i=1,…,4 に対し、

$$
	x_i,y_i : \mbox{第 i 頂点の x 座標および y 座標}
$$

などと表記する場合もあります。

　実際に quad 関数を使って四角形を描いてみます

```Java
background(250,250,250);
size(500,500);

strokeWeight(10);
stroke(0,64,255);
fill(255,0,0);
quad(70,50, 80,400, 400,300, 250,280);
```

![quad](http://gurakura.sakura.ne.jp/img/helloMondrian/quad.png)

この四角形は一見すると三角形の仲間のようにも見えますが、4 つの頂点から成る、れっきとした四角形です。

　quad 関数は指定した 4 つの頂点を結ぶ図形を描くのみですので、与えるパラメータによっては 4 角形とならない場合があります（下のプログラムと図を参照）。

そのような場合でも Processing は特にエラーや警告を出すことはありませんので、意図した通りの四角形が描画されているか、常に確認するようにして下さい。

```Java
background(250,250,250);
size(500,500);

strokeWeight(10);
stroke(0,64,255);
fill(255,0,0);
quad(70,50, 80,400, 400,300, 150,480);
```

![invalid quad](http://gurakura.sakura.ne.jp/img/helloMondrian/invalid-quad.png)
AR.js studio でロケーションベースARを作成してみた

[AR.js studio](https://ar-js-org.github.io/studio/)なるものを見つけたので、[前回](https://qiita.com/matsukatsu/items/20f5128283b4a03a5c1a)に引き続き、試してみようと思います。
今回はロケーションベースARです。

## 使い方

### Step1
ロケーションベースを選択します。
![loc1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/c501081f-1ccf-a3e7-1184-5d2695ef0e34.png)

### Step2
- 緯度経度を入力するか、地図をクリックして表示位置を入力します。
- 表示したい画像をアップロードします。
- Githubにパブリッシュするか、プロジェクトをzipでダウンロードします。
![loc2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/e5e32533-aa1a-c3fd-c157-7cd835b0e843.png)

## 動作確認
表示されました。
が、表示位置が安定しません。
![loc_min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/8d6f15ab-9c1b-eadf-a6d6-ce8aa054d403.gif)
デバイスのセンサー精度や通信環境にもよるのかもしれないですが、これだけ表示位置が定まらないと使い方に工夫がいりそうです。

## まとめ
AR.js studioでロケーションベースARを作ってみました。
簡単に作れましたが、表示位置が安定しないので、用途を選びそうです。

現状のAR.js studioだけで完結できるケースはあまりないかもしれないですが、大枠のコードを作ってもらって、あとは自分で書くものだと思えば便利かもしれません。
まだアルファ版という事なので、期待して正式リリースを待ちたいと思います。
AR.js studio でマーカーベースARを作成してみた

A-Frameで色々できるようになってきたので、ARとしての利用をもう少し見ていこうと思いました。
調べていると、[AR.js studio](https://ar-js-org.github.io/studio/)なるものを見つけました。

> AR.js Studioは、カスタムの拡張現実体験を構築するためのオープンソースのAR作成プラットフォームです。
> (中略)
> AR.js Studioを使用する場合も、コーディングの知識は必要ありません。 今すぐ最初のARプロジェクトの作成を開始できます。

との事。
今すぐ最初のARプロジェクトの作成を開始してみましょう。
ちなみに、まだアルファ版です。

> これはアルファ版です。 機能が完成していない、バグが存在する可能性があります。 

## 使い方

### Step1
マーカーベースを選択します。
![mark1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/53fba22a-d356-bd69-fbf2-1e508d85180b.png)

### Step2
表示したい画像をアップロードし、Githubにパブリッシュするか、プロジェクトをzipでダウンロードします。
![mark2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/636c181b-1f3f-afff-a423-7ac7c7a2051c.png)

Githubにパブリッシュすると、Githubとの認証後に自動的にリポジトリが作成され、Github Pages用のブランチが作成されます。

![gh-pages.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/846e6d3d-5c87-d78a-4002-024adcb59f1e.png)


## 動作確認

さっそく見てみましょう。
Githubにパブリッシュすると、最後にGithub PagesのURLが表示されるので、スマホでアクセスするだけです。
![mark_min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/abc6b988-66ba-377e-03d6-5cb8e2ed07a5.gif)
表示されました。
が、画像の上端がこちらを向いてしまい、なんだかよくわかりません。
コードを修正して、a-imageをx軸に90°回転させます。

```
rotation="90 0 0"
```

<img width="320" alt="mark-x90.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/9db4189e-efd9-4795-be3e-c7b8ff363a55.png">
画像がこちらを向きました。

## まとめ

AR.js studioでマーカーベースARを作ってみました。
簡単に作れましたが、その分細かい事は設定できません。

細かい事を設定するには、結局コードを書かないといけなさそうです。
コードを書くには、ある程度a-frameを把握しておく必要があります。
今回はARマーカーを生成しませんでしたが、そのあたりもAR.js studioが受け持ってくれるのは楽かもしれません。

まだアルファ版という事なので、期待して正式リリースを待ちたいと思います。
【jQuery】初心者メモ

JavaScript学習と並行してjQueryの学習を行うにあたり、基本的な事項をメモ。
・実習サイト：　Progate。
・ライブラリ：　  https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
・参考書：　なし（随時、ネットで検索）
※Progateについて：このサイトの宣伝ではありません。私の学習ニーズにたまたま合致しただけです。念の為。

##１．jQueryの書き方
```javascript:jQueryの書き方（基本）
$('セレクタ').メソッド(引数);  // 何を（jQueryオブジェクト）.どうするか。
```
```javascript:jQueryの書き方（同一セレクタに複数メソッド実施の場合）
//jQueryオブジェクトを格納する時は、変数の頭に$を付けるのが慣例。
var $変数名 = $('セレクタ');
$変数名.メソッド1(引数);
$変数名.メソッド2(引数);
```
```javascript:jQueryの書き方（メソッドチェーン）
$('.target').find('a').css('color', 'red');
```

##２．jQueryの実装方法(jsファイルへの記載内容）
```javascript:jQueryの実装方法
// 正式記法
$(document).ready(function(){
  // readyイベントにより、HTML全体の読み込み完了を待つ。
  // ここにjQuery本体を記載する。
});
// 省略記法
$(function(){
  // ここにjQuery本体を記載する。
});
```
##３．関連ファイルのHTMLでの参照定義箇所
```html:jQuery関連定義箇所
<head>
  // ライブラリ定義
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>

  // jsファイル参照定義（bodyの最下部を推奨）
  <script src="script.js"></script>
</body>
```


##４．CSSの変更
```javascript:CSSの変更の書き方
//CSS
.item {
  color: red;
}
//jQuety: red -> green
$('.item').css('color', 'green');
```

##５．イベント処理
```javascript:イベント処理の書き方（引数=１）
// $('セレクタ').イベント名(function(){ イベント処理 });
$('#btnOk').click(function(){
  console.log("ボタンがクリックされました。");
 });
```
```javascript:イベント処理の書き方（引数=２）
// $('セレクタ').イベント名(function(){...}, function(){...});
$('.target-hover').hover(
  function(){  // マウスを乗せた時の処理
  },
  function(){  // マウスが外れた時の処理
  }
);
```
```javascript:thisの使い方
// 選択されたリスト要素をthisで参照できる。thisはクオーテーションでくくらない。
$('li').click(function(){
  $(this).css('color', 'red');
 });
```
##６．DOM操作
１．単純なテキストの変更

```html:変更前HTML
<p>おはようございます。</p>
```
```javascript:jQuery（文字列変更／HTML変更）
$('p').text('お先に失礼します。');
$('p').html('<span>お先に失礼します。</span>');
```
２．textメソッド／attrメソッド／valメソッドの使い分け
&emsp;(1) textメソッド：　HTML要素のテキストを取得／設定する。

```html:HTML
<div>こんにちは</div>
```
```javascript:jQuery
$('div').text();     //=>  こんにちは
```
&emsp;(2) attrメソッド：　HTML要素の属性値を取得／設定するためのメソッド（value属性はvalメソッドを使う）。

```html:HTML
<img src="xxxx.jpg">
```
```javascript:jQuery
$('img').attr(src);   //=> xxxx.jpg
```
&emsp;(3) valメソッド：　value 属性の値を取得／設定するためのメソッド。

```html:HTML
<input value="こんにちは">
```
```javascript:jQuery
$('input').val();   //=> こんにちは
```

##７．(HTML) カスタムデータ属性
「data-」から始まる属性名をHTMLのタグに自由に設定できる。

```html:カスタムタグ属性定義
<div data-sample="hello">こんにちは</div>
```
```javascript:カスタムタグ属性利用
console.log($('div').attr('data-sample'));   //=> hello
```

##98．学習したイベント一覧
・clickイベント：　クリック時の処理を定義。
・hoverイベント：　マウスを乗せた時の処理を定義。hover("マウスを乗せた時の処理", "マウスが外れた時の処理")。

##99．学習したメソッド一覧
・addClass/removeClass：　指定クラス.addClass(新クラス);
・hasClass：　Yes/No = 対象クラス群.hasClass（探索クラス);
・find：　該当下位クラス = 指定クラス.find(下位クラス定義);
：fadeIn/fadeOut：　指定クラス.fadeIn();　指定クラスを徐々に表示／表示します。
・slideUp/slideDown：　指定クラス.slideUp();　各要素の高さを操作して、下から上に消えていくイメージの効果で非表示にします。 
・eq：　li要素.eq(0~の数値)；　指定数値のli要素（\<li>xxx\</li>）が取得できる。
vCenterのインストール時のホスト名を解決するためにDNSをWIN10で構築した話

# vCenterのインストール時のホスト名を解決するためにDNSをWIN10で構築した話
はい皆さんこんにちは

結論から言うとこの記事は

vCenterのアプライアンスインストール時に、ホスト名を設定するのですが、
最近のバージョンではDNS設定が必要となっていたため、BlackJumboDogを使って
WIN10環境でDNSを構築したという話です。

# 詳細

参考資料が欲しい方はこの辺見てください。
※DNSなしでインストールする方法は多くの方がまとめられていますが、個人的に分かりやすいものを掲載させて頂きました。

BlackJumboDog
http://www.sapporoworks.ne.jp/spw/

BJD設定
http://maruton-memorandum.blogspot.com/2013/06/windowsblackjumbodogdns.html

vCenter Server をDNSなしでインストール
https://qiita.com/qiitaroi/items/add3f09ba81c2d5365eb

ESXiとvCenter Server間の名前解決
https://qiita.com/tsukamoto/items/604dad01c905d75ef1b4




環境：
vCenter6.7仮想アプライアンス
ESXi6.7
DNSサーバ（WIN10）


##DNSをたてるWINDOWS環境を構築
こちらはvCenterと通信できるならどこでも良いです。
端末でも仮想マシンとして立ててもいいでしょう。
私は端末のWindows10を利用しました。

##BlackJumboDogインストール
参考URLからダウンロードして、実行するだけです。
特に難しい事は考えずYESマンで良かったと思います。

##BlackJumboDog設定
①まずはBlackJumboDogを起動（プログラム＞SAPPORO WORKS＞LaunchBJD）
②オプション＞DNSサーバ＞DNSサーバ＞DNSサーバを使用するにチェックON
　更新時間・終了時間をお好みで変更。私は30秒にしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/8c92666b-e919-43ab-9527-06e4baff18dd.png" width=50%>

③ACLタブで禁止するを選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/f02c7c15-e065-5d3b-0c21-5fd7a835f6e6.png" width=50%>

④オプション＞DNSサーバ＞ドメインの追加と削除＞ドメイン設定
　vCenterのデフォルトのvSphere.localにしています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/b69799cd-939b-72cf-fc59-71c57390cfd0.png" width=50%>


⑤オプション＞DNSサーバ＞Resource-ドメイン＞設定
　こんな感じにしました。
　※A(PTR)が入っていればとりあえず動きそうな挙動でした。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/f54d3421-217d-a1b9-ee04-a0a0977acf5b.png" width=50%>


##起動する
起動/停止＞サーバ起動
エラーになった時はコンソールにあるメッセージを確認します。

##確認
コマンドプロンプトから
nslookup VCENTER.vsphere.local 端末のIPアドレス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/97e5b38d-8b98-dab0-df85-ae8729422907.png)

このように出ていればOKです。

##感想
もともとDNSを立てた事が無かったのですが、
たまたまBlackJumboDogの事を知り、WIN10で試してみようと思い立ちました。
ツールが使いやすい事もあり、DNSサーバへの苦手意識が克服出来たような気がします。



**ありがとうございました。**