OmniAICreator/Qiita-1.07M huggingface dataset:
Route53で負荷分散をするための選択肢が増えた話

# TL;DR

Route53 を使っていて、たとえば A Record に対して複数の IP アドレスをなるべく平等に返したい場合（ただしサービスが止まっているノードは除外する）の選択肢として Routing Policy=Weighted（加重リソースレコードセット）がありますが、平等にするにはすべてに同じ重み(weight)を指定する必要があります。

ところが最近（？）Routing Policy=Multivalue Answer（複数値回答）という選択肢が増えたようで、これで毎回異なった値を平等に返してくれるようです。重みの指定は不要です（指定不可）。もちろん Routing Policy=Weighted と同様に、ヘルスチェックを関連付けておけば、ヘルスチェックで Unhealthy なノードは自動的に対象から除外してくれます。

# はじめに

フェイルオーバーのしくみを調べていたら、Routing Policy=Multivalue Answer という選択肢が出ることに気づいたのですが、これは日本語ドキュメントには載っていません。原文には載っていたので和訳が追いついていないのだと思いますが、[Route53開発者ガイド](http://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/Welcome.html)は現時点でも PDF で 420 ページという大作ですので、AWS の中の人はかなりがんばっているという印象です。

以下に、簡単に選択肢を紹介します。

# レコードセットの設定
| 項目名                           |       値／選択肢 |
|:--------------------------------|:---------------------------------------------------------|
| NAME                        | 当該ドメインのサブドメイン（ホスト名）部分|
| TYPE                        | （たとえば）A - IPv4 Address |
| Alias（Route53 固有）        |【レコードタイプが SOA/NS 以外の場合に選択可能】  <br>Yes：アクセス先が AWS が動的に割り当てる FQDN の場合、<br>　　または別のリソースレコード（同一ホストゾーン内）<br>No ：直に IP アドレスを書く場合|

## Alias=Yes の場合
| 項目名                           |       値／選択肢 |
|:--------------------------------|:---------------------------------------------------------|
| Alias Target                        | AWS 管理の FQDN（IP アドレスが動的に変わる）等|
| Routing Policy |Simple：常に同じ値を返す（デフォルト）<br>Weighted：加重による分散<br>Latency：レイテンシによる分散<br>Failover：アクティブ／スタンバイ方式による分散<br>Geolocation：アクセス元の国や地域による分散 |
| Routing Policy<br>=Weighted | Weight：加重値<br>Set ID：加重セットグループ中でユニークな文字列 |
| Routing Policy<br>=Latency | Region：対象リージョン<br>Set ID：ユニーク文字列 |
| Routing Policy<br>=Failover | Failover Record Type：Primary または Secondary<br>Set ID：ユニーク文字列|
| Routing Policy<br>=Geolocation |Location：国名や地域を選択肢から選択<br>Set ID：ユニーク文字列 |
| Evaluate Target Health| Yes：AWS 管理の FQDNのヘルスチェックと連携する<br>　　（ただし Alias 先が CloudFront の場合は選択不可）<br>No ：ヘルスチェックを考慮しない |
| Associate with Health Check | 【Routing Policy が Simple の場合は指定不可】<br>Yes：何らかのヘルスチェックに関連付ける。<br>　　ヘルスチェックが正常でない場合、返す値からそのリソースを除外する。<br>　　これを選択する場合、TTLは60以下を推奨。<br>No ：返す値の絞り込みを行わない。 |
|Associate with Health Check<br>= Yes |Health Check to Associate：関連付ける対象のヘルスチェック（選択肢から選択）|

## Alias=No の場合
| 項目名                           |       値／選択肢 |
|:--------------------------------|:---------------------------------------------------------|
| TTL（秒数）|クライアントがレコードをキャッシュ可能な時間 |
| Value |IPアドレスの値（複数可の場合もある）|
| Routing Policy | Weighted / Latency / Failover / Geolocation（これらは Alias=Yes の場合と同じ扱い）|
| Routing Policy<br>=Multivalue Answer | Set ID：ユニーク文字列<br>最大８個の中から正常なレコードを抽出し、複数の値を毎回ランダムな順序で返す。<br>Routing Policy=Simple で同じ名前を登録しようとすると二重登録エラーとなるが、Routing Policy = Multivalue Answer でかつ Set ID を異なった値にすることで、同じ名前で複数レコードを登録できる。|

# おまけ

これを調べている間に日本語マニュアルの中に[いくつか不備](https://docs.google.com/spreadsheets/d/1xWJy4cMawsODHYDwAM_8RcD-W_argY4s4pEWrRU2wSI/edit#gid=2023215642)をみつけたので、各ページ最下段にある [フィードバック] から一応報告しましたが、果たして拾ってもらえるかどうか…。
【随時更新】CakePHP2 について

これからCakePHPを勉強するにあたって、【自分のメモ用】とphpをある程度理解できたので【これからフレームワークを勉強しよう】とする方に向けてこの記事を書かせていただきます。




#コントローラーに引き継がれたリクエスト情報を確認する方法

```app/Controller/MetingRoomsController.php
public function view($id = null) {
		debug($this->request->params);//1行追加　ここでアプリケーションルート以降のURLがセットされたデータが確認できる
		if (!$this->MeetingRoom->exists($id)) {
			throw new NotFoundException(__('Invalid meeting room'));
		}
		$options = array('conditions' => array('MeetingRoom.' . $this->MeetingRoom->primaryKey => $id));
		$this->set('meetingRoom', $this->MeetingRoom->find('first', $options));
	}
```

返り値

```
http://localhost/meetingman/meeting_rooms/view/1/a:2/b:3の場合
array(
	'plugin' => null,
	'controller' => 'meeting_rooms',
	'action' => 'view',
	'named' => array(
		'a' => '2',
		'b' => '3'
	),
	'pass' => array(
		(int) 0 => '1'
	)
)
```


# ローディング処理

```app/Controller/MetingRoomsController.php
// app/ControllerディレクトリにあるAppController.phpをロードする
App::uses('AppController', 'Controller');
```

## 【コントローラー】共通の決まりごと

- コントローラークラスの名前は【キャメルケース複数形】とする
- コントローラークラスのファイル名は【コントローラー+クラス名+.php】とする
- コントローラークラスはAppControllerクラスを継承する　例：class MeetingRoomsController extends AppController
- AppControllerクラスはApp::uses()で読み込んでおく　例：App::uses('AppController', 'Controller');

#リクエスト情報の管理

```
boolean is ([種類：文字列])
```

【is()】は、そのリクエスト情報の種類をboolean でチェックしてくれる

下記の場合、$result の中に、そのhttpリクエストが【POST】かどうか判断してくれる

```
$result = $this->request->is('post');
//その他：'get','ssl','ajax'がある
```


#リダイレクトする方法
```app/Controller/MetingRoomsController.php
$this->redirect(array('action' => 'index'));
```

###※リダイレクトするときの注意点
リダイレクトは一度制御がサーバーからブラウザに映るため、【redirectの前に一覧画面に何か表示しようと思って、set()しても意味がない】ということ

↓

その場合はセッションを使い、データを保存し、データを出力する
SessionComponent::setFlash()を使用して情報をセットする

```app/Controller/MetingRoomsController.php
public function edit($id = null) {
	if($this->request->is('post')) {
		//更新処理
		if($this->MeetingRoom->save($this->request->data)) {
			//セッションにメッセージの書き込み
			$this->Session->setFlash('succeed!');
			//リダイレクト
			$this->redirect(array('action'=>'index'));
		}
	}
}
```

#Cookieファイルの操作方法

##Cookieとは
ブラウザ側に情報を保存する仕組みのこと。
CakePHPでは、Cookie機構を利用して、【セッションID】の情報を取り出している


```
$cookieName = 'YourSiteName' //Cookieの名前
$cookieKey = 'key1'; //Cookie内の識別名

//Cookieの情報を取得する（keyが存在しない場合はnullを返す）
$val = $this->Cookie->read($cookieName.'.'.$cookieKey);

//Cookieに値を保存する
$this->Cookie->write (
  $cookieName.'.'.$cookieKey,
  $val, //保存する値
  $encypt, //値を暗号化するか(省略時：true)
  $expires, //Cookieをいつまで有効とするか　省略時：ブラウザを閉じるまで有効
);

//Cookieの情報を削除する
$this->Cookie->delete($cookieName.'.'.$cookieKey);
```

#ファイルをダウンロードするアクション

```
public function sendFile($id = null) {
		$setting = array(
			// ファイルの種類
			'type' => 'txt',
			// 【名前をつけて保存】に表示されるファイル名
			'name' => 'super.txt',
			// ダウンロードファイルの内容
			'content' => file_get_contents('C:\xampp\htdocs\meetingman\app\message.txt'),
		);

		// 定義されていない種類のファイルを出力する場合は MIMEをセットする
		$this->response->type(array('txt'=>'text/plain'));

		// レスポンスヘッダの組み立て
		$this->response->type(array('txt'=>'text/plain'));

		// 画面表示は行わず、レスポンスを直接セット
		$this->autoRender = false;
		$this->response->body($setting['content']);
	}
logrotateプロセスをdocker化

インフラのMicroservice一貫でlogroateプロセスをdocker化してみました。


#ファイル構成



##ディレクトリ構成

```
Dockerfile
logrotate.conf
logrotate.d/hoge
```


##Dockerfile

```
FROM sequenceiq/logrotate 
ADD logrotate.d /etc/logrotate.d/
ADD logrotate.conf /etc/logrotate.conf
```


##logrotate.conf

```
weekly
su root
rotate 4
create
include /etc/logrotate.d
```

##logrotate.d/hoge

```
/rails/shared/log/rails.log
/var/log/nginx.log
{
  daily
  rotate 7
  missingok
  compress
  ifempty
  delaycompress
  su root
  copytruncate
  sharedscripts
}
```


#Docker image build&&push

私の場合ECRを使ってDockerイメージを管理してるので以下の手順を実行します。

##ECRログイン


```
eval "$(aws ecr get-login --region ap-northeast-1)"
```

##docker build


```
docker build -t xx.dkr.ecr.ap-northeast-1.amazonaws.com/logrotate .
```

##docker push

```
docker push xx.dkr.ecr.ap-northeast-1.amazonaws.com/logrotate
```



#docker run

以下のコマンドでdockerコンテナを立ち上げます。

```
docker run -d \
	-v /var/log:/var/log \
        -v /rails/shared/log:/rails/shared/log \
  -e CRON_EXPR="* * * * *" \
  xx.dkr.ecr.ap-northeast-1.amazonaws.com/logrotate
```

その他いろんななオプションが使えます。


```
docker run -d \
  -v /var/log:/var/log \
  -v /rails/shared/log:/rails/shared/log \
  -e "LOGS_DIRECTORIES=/var/log /var/log/nginx" \
  -e "LOGROTATE_COPIES=10" \
  -e "LOGROTATE_SIZE=10G" \
  -e "LOGROTATE_COMPRESSION=compress" \
  -e "LOGROTATE_INTERVAL=daily" \
  -e "LOGROTATE_DATEFORMAT=-%Y%m%d" \
  xx.dkr.ecr.ap-northeast-1.amazonaws.com/logrotate
```



#ECSを利用してる場合

ECSを利用してる場合は以下の手順でtask-definitionが作れます。


##task_def.jsonファイル


```
{
    "family": "logrotate",
    "containerDefinitions": [
        {
            "name": "logrotate",
            "image": "xx.dkr.ecr.ap-northeast-1.amazonaws.com/logrotate",
            "cpu": 0,
            "memoryReservation": 32,
             "environment": [
            {
              "name": "CRON_EXPR",
               "value": "* * * * *"
            }
            ],
             "mountPoints": [
               {
                 "sourceVolume": "common_log",
                 "containerPath": "/var/log"
               },
               {
                 "sourceVolume": "rails",
                 "containerPath": "/rails/shared/log"
               }
            ],
            "dockerLabels": {
                "title": "",
                "p-r": ""
            }
        }
    ],
     "volumes": [
    {
    "name": "common_log",
    "host": {
      "sourcePath": "/var/log"
      }
    },
    {
    "name": "rails",
    "host": {
      "sourcePath": "/rails/shared/log"
      }
    }
    ]
}
```

##task-def作成

```
aws ecs register-task-definition --cli-input-json file://task_def.json
```

クラスターにdockerコンテナをアップする手順は省略します。

#感想

案外にシンプルで簡単構築できました。

logrotateの設定をdockerのコードで管理できるようになりました!!
task-defのバージョン番号だけみれば最新のlogroate設定になってることを確認できるので
対応漏れ減らせそう

ただ、同じ設定なのにサーバごとにコンテナ立ち上げるのちょっとめんどい。。。各コンテナが落ちてないか監視も必要だろうし

場合によってはNFSやrsyncとかでログをすべて一箇所に集めてそこにlogrotate用dockerコンテナを立ち上げておくこともよいかもです。
iOS8にて、[UIWindow new]で生成したWindowのframe原点が、Landscape状態の画面にも関わらず、Portrait左上になってしまう現象を解決した

iOS 8から`frame`など座標を考える上で、スクリーン上で見えているOrientationの左上が原点となるようになった。
月日は流れiOS 11も出る頃なので、いい加減切りたいバージョンも増えつつある今日このごろ、
[UIWindow new]を使用するにあたって、iOS 8系でのみ発生する不具合のような挙動に直面した。

多分Swiftでも起こるのでタグ付けした。

## 何が起こるか

iOS 8でだけ、UIWindowを生成して表示したとき、Landscape表示しているにも関わらずPortraitで表示される。

## どういう状況で起こるか

- iOS 8.xである（iOS 7.x以下、iOS 9.x以上では発生しない）
- `[UIWindow new]`でWindowを生成する
- 生成したWindowは`[vc shouldAutorotate] == NO`となる`ViewController`を`rootViewController`に持つ
- 生成したWindowの`frame`をフルスクリーンにしようと`[UIScreen mainScreen].bounds`の値を使う
- Landscape状態でWindowを生成・表示する

以下は要点を抽出したコード。

```objc
// SampleViewController.h
@interface SampleViewController : UIViewController
@end
// SampleViewController.m
@implementation SampleViewController
- (BOOL)shouldAutoRotate {
    return NO;
}
@end
```

```objc
// ViewController.m
@interface ViewController ()
@property (nonatomic) UIWindow *w;
@end

@implementation ViewController
- (IBACtion)openWindow:(UIButton*)sender {
    UIWindow *w = [UIWindow new];
    w.frame = [UIScreen mainScreen].bounds;
    w.rootViewController = [SampleViewController new];

    self.w = w;
    [self.w makeKeyAndVisible];
}
@end
```

### これが

![Simulator Screen Shot 2017.08.04 11.50.52.png](https://qiita-image-store.s3.amazonaws.com/0/42032/a5aae816-dba3-6e21-1150-e98e0e741d38.png)

### こうなる

![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/42032/03638842-73e4-3c78-a4e1-5f792efbd080.png)


iOS 8だけ、UIScreenの原点と生成したWindowの原点が異なっている。

- UIScreenは見えているスクリーンの左上を原点としている
- `[UIWindow new]`によって生成された`UIWindow`は`Portrait`状態の左上を原点としている

## HACKに解決

`shouldAutoRotate`が`YES`なUIViewControllerを持たせた上で`makeKeyAndVisible`かけたら上手くいくんじゃね？という発想のもと、以下のようにしたところ上手くいった。

```objc
- (IBACtion)openWindow:(UIButton*)sender {
    UIWindow *w = [UIWindow new];
    w.frame = [UIScreen mainScreen].bounds;

    // HACK: iOS 8系にてShouldAutoRotate == NO のViewControllerを
    //       rootViewControllerに持ってmakeKeyAndVisibleを実行すると
    //       アプリケーションのInterfaceOrientationに関わらず
    //       InterfaceOrientationPortrait状態のWindowが表示されてしまう
    //       iOS 9以降では空のUIViewControllerを持たせる必要はなく、
    //       表示したいViewControllerを持たせて構わない
    w.rootViewController = [UIViewController];

    self.w = w;
    [self.w makeKeyAndVisible];

    // HACK: iOS 8系にてShouldAutoRotate == NO のViewControllerを
    //       rootViewControllerに持ってmakeKeyAndVisibleを実行すると
    //       アプリケーションのInterfaceOrientationに関わらず
    //       InterfaceOrientationPortrait状態のWindowが表示されてしまう
    //       よって空のViewControllerを持たせてmakeKeyAndVisibleを実行した後に
    //       ViewControllerを差し替える
    w.rootViewController = [SampleViewController new];
}
```

直前まで表示されていたWindowのInterfaceOrientationを元に、表示したいWindowにtransformかけるしかないのか…？という悩みから解決されて最高に気分がいい。

- [swift - iOS 8 - UIWindow Orientation Is Always Portrait - Stack Overflow](https://stackoverflow.com/questions/26916009/ios-8-uiwindow-orientation-is-always-portrait)
    - 読んだ時別件かなと思ったけど、解決した今、たしかにこの追記がベストな回答だと理解した
スマホ特有の挙動の備忘録

## 概要
スマホ特有の挙動の備忘録です。

## iOS
### videoの自動再生をオンにする
「muted autoplay playsinline」を記述すると自動再生になりました。 

```html
<video src="example.mp4" muted autoplay loop playsinline></video>
```

### iOS10 Safariでピンチイン、ピンチアウトを無効にする
iOS10 Safariでは、「user-scalable」が効きません。
そのため、ピンチイン、ピンチアウトが無効にできない場合があります。
その場合の対応方法です。

#### ピンチイン、ピンチアウトを無効にする

```html
<meta name="viewport" content="user-scalable=no">

```

iOS10 Safariの場合、上記だけでは聞かないのでjsで対応する必要があります。
https://blog.cror.net/iso10-user-scalable.html


## おそらく役立つ情報 
痒いところに手が届くかもしれない記事を書いています。
フォローしてくれるとやる気になります！

- Qiita　プログラミングに関する情報はこちら
http://qiita.com/nadonado


- Twitter　日々のつぶやきはこちら
https://twitter.com/hironado
ブログで文章や写真をコピーされないようにする方法

## 概要
ブログで文章や写真をコピーされないようにする方法です。

## 最初にやること
まずは、コピーライトを入れましょう。

## 次にやること
写真にコピーライトを入れましょう。
wordpressのサイトであればプラグインで入れらます。

### Easy Watermark
https://ja.wordpress.org/plugins/easy-watermark/

## それでもコピーされるときは
右クリックを禁止しましょう。

```html
<body onMouseDown="return false;" onSelectStart="return false" oncontextmenu="return false;">
```

画像が取られるのが嫌なときは、

jQuery
```js
<script>
    $(function () {
        $('img').attr('onmousedown', 'return false');
        $('img').attr('onselectstart', 'return false');
        $('img').attr('oncontextmenu', 'return false');
    });
</script>
```

## それでもソースコードから取ることは可能、閲覧後がわかっているなら

最終手段として魚拓を取りgoogleへ通報します。
それも聞かなければ、略式裁判という方法もあります。
業者などが悪質にやっている場合などはきちんと対応したいですね。

## おそらく役立つ情報 
痒いところに手が届くかもしれない記事を書いています。
フォローしてくれるとやる気になります！

- Qiita　プログラミングに関する情報はこちら
http://qiita.com/nadonado


- Twitter　日々のつぶやきはこちら
https://twitter.com/hironado
【Git】よく使うコマンドを復習

## 概要
Gitでよく使うコマンドの復習です。
プログラマーに教えてもらったので、メモ。

## リベース
例えば、developを基準にして開発していて、自分がマージするときにそのdevelopが進んでいたりするとマージにリスクがあるため、リスクを軽減した方が良い場合があります。
その場合、基準にしたdevelopブランチを最新にしておくとリスクが減ります。
このように、リベーストは基準にしたブランチを変更したいときに行う手順です。

以下の手順で作業します。
1. リベースしたいブランチはチェックアウトし、コミットして起きます。
2. グラフ上でベースにしたいブランチを右クリックし、「リベース」をクリックします。
3. 特にコンフリクトが起きなければこちらで完了です。


## featureブランチの切り方
1. リモートのdevelopブランチをダブルクリック
2. 新規ローカルブランチ名を「feature/0000」にします。
3. 「ローカルブランチにリモートブランチを追跡させる」のチェックを外します。
4. OKをクリックします。


## masterの位置の写し方
デプロイの関係で複雑な手順になっています。
一般的なプロジェクトだとマージすればいいだけだから、あまり参考にならないかも。

1. 修正したデータををプッシュする。
2. ブランチmasterをダブルクリック
3. プッシュしたfeatureブランチを右クリックして、「このコミットまでmasterを戻す（Heard）」をクリック。
4. headと出た場合プッシュする（（↑3↓1）となった場合は下記を参考に）
5. 自動的にデプロイになり、stagingに反映する

※masterの位置を変えた時に（↑3↓1）の用になった場合
focusを行います（基本的にはやってはいけない）
ターミナルでプロジェクトの階層まで移動します（「ls、cd」を使う）
そこで下記のコマンドを打ちます。
sudo git push -f origin master
マシンのパスワード、gitのパスワードが聞かれたら打ち込みます。


## プルリクを出す。
1. featureブランチの対象となる番号を右クリックしてメニューを出し、一番下の「プル リクエストを作成…」をクリックします。
2. baseをdevelopに変更します。
3. タイトルにredmineのチケットタイトルを書く
4. コメント欄にredmineのurlを入力します。
5. プル リクエストを出します。

## developの修正を取り込む
1. 修正しているfeatureブランチをダブルクリックする
2. developのコミットを右クリックして「マージ」を選択する。
3. 競合していなければ、developの位置がfeatureブランチに移動する。

## おそらく役立つ情報 
痒いところに手が届くかもしれない記事を書いています。
フォローしてくれるとやる気になります！

- Qiita　プログラミングに関する情報はこちら
http://qiita.com/nadonado


- Twitter　日々のつぶやきはこちら
https://twitter.com/hironado
JavaScriptのforEach

# 概要

- Javascript(ECMAScript)のforEachの自分メモ
- 参考リンク
    - https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

# サンプル1

#### ソース
```js
["apple", "orange", "pine"].forEach(function(item, index){
    console.log(index + ":" + item);
});
```

#### 結果

```
0:apple
1:orange
2:pine
```

# サンプル2

#### ソース
```js
const maps = [
    {key: "k1", val: "value1"},
    {key: "k2", val: "value2"},
    {key: "k3", val: "value3"},
];
maps.forEach(function(item, index){
    console.log(index + ":" + item["key"] + "=" + item["val"]);
});
```

#### 結果

```
0:k1=value1
1:k2=value2
2:k3=value3
```
【PHP Storm】でよく使うショートカット

## 概要
PHP Stormでよく使うショートカットです。
使う項目が増えたら、徐々に増やしていきます。

## 編集

|  ショートカット  |  動作  |
| 　:---- | :---- |
|  command + alt + L  |  コードの自動整形  |
|  alt + ↑ or alt + ↓  |  閉じタグまでを選択  |
|  Control + g  |  同一単語を選択（繰り返すと次の単語も選択）  |
|  Control + Shift + g  |  選択した単語を一つ前つ前の状態にする  |
|  Control + Command + g  |  同一単語をすべて選択  |


## 検索置換

|  ショートカット  |  動作  |
| :---- | :---- |
|  Control + f  |  検索  |
|  Control + Shift + f  |  一括検索  |
|  Control + r  |  置換  |
|  Control + Shift + r  |  一括置換  |


## サーバー

|  ショートカット  |  動作  |
| :---- | :---- |
|  command + alt + shift + x  |  アップロード  |

## おそらく役立つ情報 
痒いところに手が届くかもしれない記事を書いています。
フォローしてくれるとやる気になります！

- Qiita　プログラミングに関する情報はこちら
http://qiita.com/nadonado


- Twitter　日々のつぶやきはこちら
https://twitter.com/hironado
[Java][Microsoft] SQL ServerのJDBCドライバをひとつのjarに含めるとき注意するべきこと

# 前段

[Maven Shadeプラグイン](https://maven.apache.org/components/plugins/maven-shade-plugin/index.html)便利ですね。
長ったらしいクラスパスを書かなくても、jarファイル一発でプログラム起動できます。

そんなjarファイルに、Microsoft SQL ServerのJDBCドライバを入れようとして起きたことです。


# やったこと

* sqljdbc4.jarをダウンロードしてきて、ローカルのMavenレポジトリに格納しました。
* pom.xmlに先のsqljdbc4.jarへの依存性を記載しました。
* shadeプラグインでひとつのjarにまとめるようにしました。


# 起きたこと

実行すると、こんなエラーで落ちました。

```
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes 
```

同じ問題にあたっているひと → https://social.msdn.microsoft.com/Forums/sqlserver/en-US/f5c69fee-8c68-4601-bfcb-376e21dfa809/sql-server-jdbc-javalangsecurityexception-invalid-signature-file-digest?forum=sqldataaccess

# 原因

sqljdbc4.jarの中に署名が入っているから？
↑
ぜんぜんわかってないです。

# 解決策

sqljdbc4.jarに含まれている署名ファイル(?)を、最終ｊａｒに含めないようにします。

```xml:pom.xml
(snip)
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
（snip）
                <configuration>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
(snip)
```

# ひとりごと

Javaがjarファイルをどのように扱って実行しているのか、理解しないとですね。。。
特定のバージョンの公式dockerイメージを使う方法

# はじめに
　CentOS7系のイメージを使おうと、dockerfileに __FROM centos:centos7.1__ と書いてもダメで調べました。当たり前過ぎて誰も書かなかったのかもしれませんが、備忘用に。


## dockerの公式リポジトリの場所
- https://hub.docker.com/

## 現在サポートされている公式イメージを調べる方法
1. 上記URLの公式リポジトリから、該当するイメージ(apache、mysql等)を選択する
2. __Supported tags and respective Dockerfile links__を確認する


## (例) dockerfileで公式のcentos7.1イメージを利用する
1. 上記、公式リポジトリから「centos」を選択する
2. __Supported tags and respective Dockerfile links__で centos7.1のタグが __centos7.1.1503__  であることを確認する
3. dockerfileにて、以下のように指定する

```dockerfile
FROM centos:centos7.1.1503

# 以下略...
```

## 最後に
　~~dockerでsystemdを使う場合、__--privileged__オプションを利用するとよい、との記事が散見されるのですが、現状のdocker(docker 17.06.0-ce)ではオプションを付けても非常に不安定になりました。古いバージョンを使っても同様。systemdを使わず、直接プログラムを起動すると上手くいくのですが... orz~~
　VirtualBox上で動作させると不安定になることがわかりました。なんでだろう...
Hogan.jsからHandlebars.jsに乗り換える


# 動機
絶対に必要な作業ではありません。
ほぼ同じ機能を持つテンプレートエンジンです。
どちらか１つにまとめたい気持ちです。

## Release状況
枯れているライブラリであり、大きな変更があるとは思えません。
ですが、万が一セキュリティに関わるようなバグがあった場合に対応が遅いと困ります。
近年のRelease状況を確認してみます。


### Handlebars
2017年5月にリリースあり
https://github.com/wycats/handlebars.js/releases


### Mustache
2016年にリリースあり
https://github.com/janl/mustache.js/releases

### Hogan.js
2014年（3年前）で止まっている
https://github.com/twitter/hogan.js/releases

Twitter社製のライブラリとはいえ、メンテナンスが控えめになることがあるようです。


# 手順
次の手順で、Hogan.jsからHandlebars.jsに乗り換えます。

1. `npm i handlebars`
1. `require('hogan.js')`を`require('handlebars')`に置き換え
1. `template.render(data)`を`template(data)`に置き換え
2. `npm uninstall hogan.js`

## 環境
[npm](https://www.npmjs.com/)でインストールして（ブラウザで動かす場合は）[browserify](http://browserify.org/)等で変換して使う想定です。
scriptタグで読み込んで使っている場合は、適当に頑張ってください。

## APIの差

上記の手順を確認するため、両者のAPIの差を整理します。
Hogan.jsのexampleを参考にして比較してみましょう。

### Handlebars.js

```js
const data = {
  screenName: "dhg",
}

const template = Handlebars.compile("Follow @{{screenName}}.")
const output = template(data)
```

### Hogan.js

```js
const data = {
  screenName: "dhg",
}

const template = Hogan.compile("Follow @{{screenName}}.")
const output = template.render(data)
```

export先がdefaultかrednder関数かの違いぐらいしかありません。

# 参考
- [Handlebars.js vs Hogan.js vs Mustache Comparison | StackShare](https://stackshare.io/stackups/handlebars-vs-hogan-vs-mustache)
- [Mustache vs Hogan.js vs Handlebars.js - yohjizzz's Blog](http://yohjizzz.hatenablog.com/entry/mustache-vs-hogan-js-vs-handlebars-js)
API Gateway + Lambdaで任意のURLにリダイレクトする方法


Web開発をしているときに、クライアントからアクセスされたサーバーでリダレクトさせたい場合があるとします。

そのとき、サーバーを立ててWebサーバーをインストールしてredirectの設定をして...等行うと思いますが、それをAWSのサービスでサーバレスに行う方法を紹介します。

これは、


「Webサーバーリクエストを受け付けて、リダイレクト処理 + ちょっとしたロジック」

を

「API Gatewayでリクエストを受け付けて、Lambdaでリダレクト用のヘッダーを作成 + ちょっとしたロジック。それを、API Gatewayでまた返却」

という形で実現します。

使用するサービスはタイトルにもあるように、

- API Gateway
- AWS Lambda

Lambda上のランタイムは、

||version|
|---|---|
|Node.js|v6.10|

となります。

これら作るのは

あるURLにGETメソッドのクエリパラメータにリダイレクトするという機構です。

さて、実際には以下の作業を行っていきます。

- Lambdaにロジックを記述
- API Gatewayの設定をする

Lambdaを先に設定するのは、API Gatewayの設定中、Lambdaを設定する箇所が出てくるからです。

# Lambdaにロジックを記述

以下のようにコードを記述します。

```js:index.js
exports.handler = (event, context, callback) => {

    var location = decodeURI(event["params"]["target"])

    context.succeed({"Location": location});
};
```

`event["params"]["target"]` : eventオブジェクトのtargetがgetのパラメータと紐付いてます。


# API Gatewayの設定をする

- APIの作成
- Lambdaの設定
- 統合リクエストの設定
- メソッドレスポンスの設定
- 統合レスポンスの設定

# APIの作成/Lambdaの設定

# 統合リクエスト

[本文マッピングテンプレート]から[Content-Type]として、　`application/json` を追加します。

![スクリーンショット 2017-08-03 16.04.01.png](https://qiita-image-store.s3.amazonaws.com/0/88357/29787dbd-79d2-8ddf-2d75-0e02212b0139.png)

テンプレートとしては、以下を追加します。

```
{
  "params": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
    #end
  }
}
```

これにより、GETメソッドのparameterをeventオブジェクトのkey, objectに展開できます。

# メソッドレスポンスの設定

デフォルトで、HTTPのステータスコードが200がレスポンスとして設定されているので、それを削除します。

[レスポンスの追加]より、ステータスコード302を追加します。

[302 のレスポンスヘッダー]において、

Locationを追加します。

![スクリーンショット 2017-08-03 15.53.11.png](https://qiita-image-store.s3.amazonaws.com/0/88357/60bf06b5-e1f2-6243-15f5-8ee9eb9c7cf4.png)

# 統合レスポンスの設定

[メソッドレスポンスのステータス]が302のものを追加します。ステータスが200のものは消します。

次に
[ヘッダーのマッピング]でメソッドレスポンスより追加した「Location」がレスポンスヘッダーとして表示されているので、それに対応するマッピングの値として、 `integration.response.body.Location` を追加します。

![スクリーンショット 2017-08-03 15.55.12.png](https://qiita-image-store.s3.amazonaws.com/0/88357/41c1afb0-4eda-af71-d17b-2345386d003c.png)

これにより、LambdaでのLocationの値が、レスポンスヘッダー「Location」にマッピングされるようになります。

# 実行してみる

[ステージ名]を `test` 等にして、APIをDeployすると、

```
 https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/test
```

と呼び出し用のURLが発行されます。

```
https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/test?target=https%3A%2F%2Fwww.google.co.jp
```

のようにブラウザからアクセスしてみましょう。リダイレクトされるはずです。



# 参考
- [Redirection in a Serverless API with AWS Lambda and Amazon API Gateway](https://aws.amazon.com/jp/blogs/compute/redirection-in-a-serverless-api-with-aws-lambda-and-amazon-api-gateway/)
- [AWS API-Gateway でLambdaの結果に合わせてリダイレクトする](http://qiita.com/takyam/items/1789b4bea02f608e7a05)
- [API Gateway と Lambdaを使ってサーバレスでいい感じのリダイレクト環境を作る](http://dev.classmethod.jp/etc/api-gateway_lambda_redirect/)
PIL のイメージをバイナリーに変換

PIL で処理したデータをバイナリーに変換する方法です。

```py3
output = io.BytesIO()
img_pil.save(output, format='JPEG')
image_jpg = output.getvalue()
```

応用例として、PIL でリサイズしたイメージを、CouchDB に保存する方法です。
CouchDB のデータベースは、jpg です。
入力データは、A0001.jpg です。

```py:resize_couchdb.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#	resize_couchdb.py
#
#						Aug/04/2017
#
import sys
import io
import requests
#
from PIL import Image
# --------------------------------------------------------------------
def image_resize_proc(image_pil):
	width, height = image_pil.size
	print(width, height)
	width_new = int(width / 2 + 0.5)
	height_new = int(height / 2 + 0.5)
	resize_img = image_pil.resize((width_new, height_new))
	width, height = resize_img.size
	print(width, height)
#
	return resize_img
# --------------------------------------------------------------------
# [4]:
def to_couchdb_proc(url_jpg_file,image_jpg):
#
	headers = {'Content-type': 'image/jpeg'}
	try:
		rr=requests.put(url_jpg_file,data=image_jpg,headers=headers)
		print(rr)
		print(str(rr.content,'utf-8'))
		print()
		print(rr.headers)
	except Exception as ee:
		sys.stderr.write(str(ee) + "\n")
#
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
#
jpg_in = "A0001.jpg"
array_a = jpg_in.split(".")
key = array_a[0]
sys.stderr.write("key = " + key + "\n")
#
img_pil = Image.open(jpg_in)
#
img_pil = image_resize_proc(img_pil)
#
output = io.BytesIO()
img_pil.save(output, format='JPEG')
image_jpg = output.getvalue()
#
url="http://localhost:5984"
url_jpg_file = url + "/jpg/" + key + "/" + jpg_in
#
to_couchdb_proc(url_jpg_file,image_jpg)
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

CouchDB にデータが保存されたことを確認

```text
$ curl -X GET --noproxy localhost http://localhost:5984/jpg/_all_docs
{"total_rows":1,"offset":0,"rows":[
{"id":"A0001","key":"A0001","value":{"rev":"1-ac131d333b4c4ad99659cda53310843d"}}
]}
```
Angular4のPipe - 配列をソートするパイプの例

Angular4にはAngular1系のFilterの代わりにPipeという機能があります。
デフォルトでは以下のパイプが存在します。

- DatePipe（日付）
- UpperCasePipe（大文字）
- LowerCasePipe（小文字）
- CurrencyPipe（通貨）
- PercentPipe（パーセント）
https://angular.io/guide/pipes#built-in-pipes

つまり上記以外はカスタムパイプとして自分で作らなきゃいけないんですね。
Filterの頃はソートとかあったのですが、そういうのも自分で作らないといけないです。めんどくさ。
　参考・カスタムパイプ
　　https://angular.io/guide/pipes#custom-pipes

パイプの定義とかはあんまわかってないので、公式ドキュメントとか見てください。
スタックオーバーフローでパクってきたソート（降順）のPipeを置いておきます。
適当にいじって使ってみてください。

```ts:order-by-pipe.ts
 import { PipeTransform, Pipe } from '@angular/core';
 
 // 配列をObjectのKeyの降順でソートするパイプ
 @Pipe({
   name: "orderBy"
 })
 export class OrderByPipe implements PipeTransform {
   transform(array: any[], field: string): any[] {
     if(array && array.length > 0) {
         array.sort((a: any, b: any) => {
         if (a[field] > b[field]) {
             return -1;
         } else if (a[field] < b[field]) {
             return 1;
         } else {
             return 0;
         }
         });
     }
     return array;
   }
 }
```

テンプレートでは以下のように書きます。
今回はIonicの例。

```ts:test-template.html
   <ion-list>
     <ion-item *ngFor="let object of objectArray | orderBy:'price'">
       <ion-avatar item-start>
         <img src="assets/images/{{ object.imageName }}">
       </ion-avatar>
       <h2>{{ object.name }}</h2>
       <p>{{ object.price }}</p>
     </ion-item>
   </ion-list>
```

上記のobjectArrayの中身はこんな感じかな。

```ts:object.ts
 let objectArray = [
   {
     'name':'ボールペン',
  	'price':100
    },
   {
     'name':'鉛筆',
  	'price':60
    },
   {
     'name':'消しゴム',
  	'price':120
    },
 ];
```

ちなみにapp.module.tsにも書いておかないと動かないっす。
パイプを置いてある場所からimportして、NgModuleのdeclarationsにも追記します。

```ts:app.module.ts
 import { NgModule, ErrorHandler } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
 import { MyApp } from './app.component';
 // 画面
 import { DetailPage } from '../pages/detail/detail';
 import { HomePage } from '../pages/home/home';
 import { TabsPage } from '../pages/tabs/tabs';
 // カスタムパイプ
 import { OrderByPipe } from '../utilities/order-by-pipe';
 
 import { StatusBar } from '@ionic-native/status-bar';
 import { SplashScreen } from '@ionic-native/splash-screen';
 
 @NgModule({
   declarations: [
     MyApp,
     DetailPage,
     HomePage,
     TabsPage,
     OrderByPipe,
   ],
   imports: [
     BrowserModule,
     IonicModule.forRoot(MyApp)
   ],
   bootstrap: [IonicApp],
   entryComponents: [
     MyApp,
     DetailPage,
     HomePage,
     TabsPage
   ],
   providers: [
     StatusBar,
     SplashScreen,
     {provide: ErrorHandler, useClass: IonicErrorHandler}
   ]
 })
 export class AppModule {}
```
Xmarin.Macアプリでネイティブメソッドの動的ロードを含むビルドを行う


ネイティブライブラリの動的ロードを含む`Xamarin.Mac`アプリを作ろうとしたら、ビルドエラーに遭遇しました。

# TL;DR
- `MMP : error MM5109: Native linking failed with error code 1`というビルドエラーを解決したい。
- プロジェクトオプション-「Mac Build」タブ-「追加のmmp引数」に「`--link_flags="-Wl,-undefined,dynamic_lookup"`」と設定する。
- `Xamarin.Mac`アプリのプロジェクトに、動的ロードで解決するメソッドが含まれていてもビルド出来るようになる。

# `MMP : error MM5109: Native linking failed with error code 1`
`Xamarin.Mac`プロジェクトをビルドするとき、`C#`のアプリをネイティブアプリに変換する処理が走ります。このとき、`C#`の中でネイティブライブラリを動的にロードしているようなプロジェクトは以下のようなエラーでビルドが止まることがあります。`_C_FooFunction`、`_C_BarFunction`は動的にロードするライブラリの中で宣言されているメソッドです。

```
Target _CompileToNative:

...

    xcrun -sdk macosx clang -g -mmacosx-version-min=10.12 -arch x86_64 -fobjc-runtime=macosx -ObjC -u _C_FooFuncion -u _C_BarFunction  ....
    Undefined symbols for architecture x86_64:
      "_C_FooFunction", referenced from:
         -u command line option
      "_C_BarFunction", referenced from:
         -u command line option

...

    ld: symbol(s) not found for architecture x86_64
    clang : error : linker command failed with exit code 1 (use -v to see invocation)
    
    MMP : error MM5109: Native linking failed with error code 1.  Check build log for details.
Done building target "_CompileToNative" in project "CocoaApp.csproj" -- FAILED.
```

# `mmp`の`--link_flags`経由でリンカーにオプションを渡す

ネイティブアプリにするビルドの過程で`clang`が呼ばれ、そのなかでリンカー(`ld`)がシンボルを解決出来ないようでした。ビルド過程の`ld`コマンドにオプションを渡して、シンボルが未解決でもビルドを完了させるようにします。

- VSforMacでプロジェクトの「オプション」ウインドウを開く
- 「Mac Build」タブを選択する。
- 「追加のmmp引数」という入力欄に、「`--link_flags="-Wl,-undefined,dynamic_lookup"`」を追記する。

![link_flags.png](https://qiita-image-store.s3.amazonaws.com/0/20175/4eea2aa0-b2f4-d26d-5f09-c21a2ce8fc86.png "link_flags.png")


これで未定義のメソッドが合っても、ビルドエラーが発生しなくなります。
当然実行時エラーが発生する恐れがあるので、ビルドしたアプリが正しく動くかは別途確認が必要です。`mmp`に渡せるオプションは他にもいくつかあるのですが、Web上にあまり情報がありません。オプションの調べ方は別記事にまとめました。

[Xamarin.Macプロジェクトのオプションにある「追加のmmp引数」に指定できる値](http://budougumi0617.github.io/post/2017/07/26/xamarin-mmp/)

ちなみに、「追加のmmp引数」近くに「リンカーの動作」というオプションもあるのですが、これでは解決しませんでした。


# 参考

[Error when making dynamic lib from .o](https://stackoverflow.com/questions/14090257/error-when-making-dynamic-lib-from-o)

[Xamarin.Macプロジェクトのオプションにある「追加のmmp引数」に指定できる値](http://budougumi0617.github.io/post/2017/07/26/xamarin-mmp/)

この投稿は自ブログからの転載です。
[Xmarin.Macアプリでネイティブメソッドの動的ロードを含むビルドを行う](https://budougumi0617.github.io/post/2017/08/04/xamarin-link-flags/)
技術的には簡単

# what is this?
[The technology is the easy part](https://speakerdeck.com/benbalter/the-technology-is-the-easy-part) から学んだこと

---
どうやるかは、何をやるかと同じくらい重要。

- 簡単な問題には既に解法がある。
- オープンソースは代替技術ではなく哲学

---
# オープンソースの手法

- デジタル方式
- 広く提供
- 非同期
- ロックなし

---
## コンウェイの法則
組織のシステムは組織のコミュニケーション構造に制約される

## 官僚主義は生きもの
「No」の文化は組織の免疫系

---
# 組織内起業のライフサイクル
1. とにかくまずはやってみる
2. 必要なツールの獲得を追求する
3. めざす文化を植え付ける

---
1. 管理制約と文化制約
2. 技術制約と文化制約
3. 施策制約と文化制約

文化が強ければ、手続きの必要は下がる。文化が強ければ、皆が正しいことをすることを信じる事ができる。メンバーは独立し自律する。メンバーが起業的になるのだ。

組織にちょっとした文化を植え付けよう。

---
強いイノベーション文化がない組織は、みな同じ結末、すなわちイノベータのジレンマ、に落ち込む。

- 組織は現状維持を好む
- 組織はいろんなことを経験してんだよ

---
## 大きめの組織の特性
### リスク回避
- バッチサイズ大きめ
- 変化が10年単位

### 技術リーダーシップ欠如
- スーツに優しくギークに厳しい制度
- 本業を軽視、技術的課題を放置

---
## 大きめの組織の特性 cont'd
### スケールダウンしないプロセス
- メンバーを信用しないプロセス
- ベンダを信用しないプロセス
- 顧客を信用しないプロセス

### 不格好を好まない

### 流れを外れるとえらく面倒になる
---
# 技術で文化を変える12の方法

---
## イノベーティブな技術の特性
- リーン
  - よりライトウェイトになれるなら、作り込みすぎである。
- イテレーティブ
  - ver.1 で困らないなら、 リリースが遅れたのだ。
- 脱中心的
  - システム的にも人的にも単一障害点がなく、判断は群衆に任されている。
- オープン
  - 情報が自由に流れないなら、摩擦がある。

---
## イノベーティブな取り組み
- 一般的ではなく理想的なユースケースに最適化する
- コードは最大でも成果の1/3。文化の伝え手になる。
- イエスと言えない人からのノーは無視する。
- 出荷により相手を押さえ込む。
- 出口戦略がある。
技術系記事まとめ

Qiita以外の技術系の記事で参考になると感じた記事をまとめてみます。

* [ELF実行ファイルをobjdumpでCのソースコード付きで逆アセンブルする方法 - C言語入門](http://kaworu.jpn.org/c/ELF実行ファイルをobjdumpでCのソースコード付きで逆アセンブルする方法)
Ghost 1.0 on NixOS

I just upgraded [my blog](https://blog.b123400.net/ghost-1-0-on-nixos/) to [Ghost] 1.0 (Well, 1.4 actually, because they are [releasing new versions crazily](https://twitter.com/JohnONolan/status/893081753426046976)). Getting things to work on NixOS is not as straight forward as other OS, so I am taking notes on how did I get it working and hopefully help someone.

The codes are here: https://github.com/b123400/nix-configs/tree/master/blog2

Ghost recommends [Ghost-CLI] for installing and upgrading Ghost, but that is clearly impure and does not work with NixOS. The Nix way to model the package is to create Nix derivations that include everything from NodeJS to all node modules, with something like [npm2nix].

**The first problem, npm2nix does not work.** [One of the dependencies](https://github.com/TryGhost/Ghost/blob/9009f2136838667e13ef04a3876b66f5b49d1e75/package.json#L35) of Ghost is specified as tarball and npm2nix cannot understand it, which results in incomplete output. The solution is to change it to git url that points to the same commit.

**The second problem, missing dependencies for some modules.** Knex is a package that requires the `mysql` package at runtime, but it is not specificed in its `package.json` ¯\\_(ツ)\_/¯ . Since the `mysql` package is required by Ghost, it is already installed at the top level and should be fine in a normal node project, but the structure in NixOS is different. Nix's [buildNodePackage] creates folder structure that limit the loadable modules to strictly what's specified in `package.json`, which means Knex is not able to `require('mysql')`. The "solution" is to manually [add the dependency](https://github.com/b123400/nix-configs/blob/2b53cb63fbb6747f8540348c3a1631724a9bda0b/blog2/node-packages.nix#L6610) in the generated file.

There is also another package that [is not specifying its dependencies properly](https://github.com/cobbspur/brute-knex/pull/1), so that needs patching as well. 

**The third problem, Knex checks package.json.** If you are using sqlite, you would see Knex refuse to start even it can requires `sqlite3`. The reason is Knex wants to be clever on dependencies, it reads `package.json` and assert `sqlite3` to be under the `dependencies` dictionary. This is suppose to be done by asking the user to run `npm install --save` manually, but that workflow again does not work on NixOS. So [another patch](https://github.com/b123400/nix-configs/blob/2b53cb63fbb6747f8540348c3a1631724a9bda0b/blog2/default.nix#L34-L39) is needed.

After fixing the above problems, it is pretty easy to setup the rest. By the way I was trying to [add Ghost](https://github.com/NixOS/nixpkgs/pull/24936) to the nixpkg repository but it wasn't going well, the generated `node-packages.nix` is huge and they are not accepting it... Wonder if there is a better way to package it.

[Ghost]: https://ghost.org
[Ghost-CLI]: https://github.com/TryGhost/Ghost-CLI
[npm2nix]: https://github.com/NixOS/npm2nix
[buildNodePackage]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/web/nodejs/build-node-package.nix
rails_adminで Uncaught TypeError: Cannot read property 'push' of undefined って怒られる

## エラーがとまらない

Rails 5.1でJquery3を読み込んでるせいで、
```
Uncaught TypeError: Cannot read property 'push' of undefined
```

ってエラーがとまらないんだけど、なんでjquery3読み込んでいるのかなとおもったらjquery-railsじゃなくて、rails_assetsが犯人でした。

``` Gemfile.lock
-    rails-assets-jquery (3.2.1)
+    rails-assets-jquery (1.9.1)
```

なので、Gemfileで明示的に1.9.1を指定して終わり。

``` Gemfile
  gem 'rails-assets-jquery', '= 1.9.1'
```
ハイパーバイザーのメモ

# ハイパーバイザーについての筆者用のメモ
気分が乗ったら情報を整理、追加していく

## 名前の由来
```text:wiki引用
IBMが「オペレーティングシステム」と呼んだためにその用語が普及したが、一般にはOSのことをスーパーバイザとも言う。
「ハイパー」という語は、「スーパー」のさらに上という意味で使われることが一般にあるが、ここではそのような意味で、OSをさらに管理する層、というような意味である。
```

## ハイパーバイザーの種類
* Type1: ベアメタルハイパーバイザー
* Type2: ホストハイパーバイザー

## ベアメタルハイパーバイザー
ハードウェア（material）の上に、直接ハイパーバイザーを乗っける。
以下引用のXenはawsのec2に現在進行形で利用されている実績がある。(2017-08-04現在)

```text:wiki引用
この方式のハイパーバイザはIBMが1960年代に開発したCP/CMS が最初で、現在のIBM z/VMの祖先である。最近の例では以下がある。
Xen
VMwareの ESX、ESXi、vSphere
L4マイクロカーネル
TRANGO
マイクロソフトのHyper-V
LinuxのKernel-based Virtual Machine(KVM)
SELTECHのFOXvisor
```

## ホストハイパーバイザー
これは皆んなが馴染みあるタイプのハイパーバイザー
よく他の環境も使いたいなぁと思い、OSの上にインストールするVMWareやVirtual Boxなどのアプリケーションに使われてる技術がこれである。

```text:引用
ハードウェア上でまず別のOSが稼働し（このOSをホストOSと呼ぶ）、その上でハイパーバイザが（ホストOSのアプリケーションとして）稼働し、更にはハイパーバイザの上で更に別のOS（このOSをゲストOSと呼ぶ）を稼働させる方法である。狭義においては、Type 2はハイパーバイザには含まれない。
例としては以下のものがある。
VMwareのVMware Server、VMware Workstation、VMware Player、VMware Fusion
マイクロソフトのVirtual PC（Windows 7専用のWindows Virtual PCを含む）とMicrosoft Virtual Server
オラクルのVirtualBox
パラレルスのParallels WorkstationとParallels Desktop
オープンソースのQEMU
オラクルのSolarisのKernel Zone
```

ハイパーバイザーといったら、本来はtype1のベアメタルハイパーバイザーを指す
Matplotlib > plt.clf() [Clear the current figure] の理由 | plt.get_fignums()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.1.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

現在読んでいるPython/Numpy/Scipy/Pandas/Matplotlib/Numba/Numexpr/...に関する本の中で、以下のような記述がある。

```
...
plt.figure(略)
plt.clf()
plt.axes(略)
...
```

plt.clf()といのはClear the current figure.という意味のようだ。
https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.clf.html

Matplotlibでセル単位で描画コードを走らす場合、「前の図」というのが残っているわけではないように思う。
そのため、plt.clf()は不要なのではないかと思っている。

あるいは、plt.figure(略)の描画が残すものをクリアするという意味なのかもしれない。

実際の動きについては未確認。

### コード例

[Fancybox Demo](https://matplotlib.org/devdocs/gallery/shapes_and_collections/fancybox_demo.html#sphx-glr-gallery-shapes-and-collections-fancybox-demo-py)
においては以下のようにtest_all()の最初でplt.clf()を行っている。

```py
def test_all():
    plt.clf()
```

### link

[When to use cla(), clf() or close() for clearing a plot in matplotlib?](https://stackoverflow.com/questions/8213522/when-to-use-cla-clf-or-close-for-clearing-a-plot-in-matplotlib/8228808)

> Whereas this one will produce a list with five figures on it.

```py
for i in range(5):
    fig = plot_figure()
    fig.clf()
# This returns a list with all figure numbers available
print(plt.get_fignums())
```

先に5つのfigureを作り、（それをクリアしてから）後で再利用する、という意味なのかもしれない。
Go/Java SE環境のElastic BeanstalkでHTTPをHTTPSにリダイレクトする

まとめるまでもなかったのかもしれませんが自分がかなりハマってしまったので書いておきたいと思います。

## 前提
基本的なSSLのセットアップができている前提で進めていきます。Elastic Beanstalk (EB) の環境にElastic Load Balancer (ELB) が紐付けされており、ELBに対して適切なSSL証明書とHTTPS/ポートの設定されているか今一度ご確認ください。

## リダイレクトの設定
ELBは受け取ったリクエストのプロトコルをX-Forwarded-Protoヘッダに格納してあるため以下の設定をnginxのサーバブロック内に読み込ませればHTTP→HTTPSのリダイレクトが実現できます。

```nginx
if ($http_x_forwarded_proto != 'https') {
    rewrite ^ https://$host$request_uri? permanent;
}
```

## nginxの設定
では肝心のnginxの設定はどうやって上書きするのか。[Go](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/go-environment.html)/[Java SE](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/java-se-platform.html)環境では簡単にnginxの設定をいじくるための仕組みが導入されています。どちらも設定方法は同じです。

`.ebextensions/nginx/nginx.conf`というファイルを作ってEBでデプロイするアプリケーションのルートディレクトリに置いておくとこの`nginx.conf`がEC2上の`/etc/nginx/nginx.conf`に上書きされます。

もう一つ、`.ebextensions/nginx/conf.d/*.conf`にファイルを置いておくとこれらのファイルが`/etc/nginx/conf.d/elasticbeanstalk`コピーされ、`nginx.conf`を上書きしていない場合はその中の`server{}`ブロックの中で、あるいは`nginx.conf`を上書きしている場合は`include conf.d/elasticbeanstalk/*.conf;`と記述すればそこで読み込んでくれますが、なぜか上記のリダイレクト設定を記述したファイルを`.ebextensions/nginx/conf.d/02_proxy.conf`として置くとnginxの設定ファイル読み込み時にif文が許されず弾かれます。

### 注意
CodeBuildを噛ましている場合、artifactを出力する際に.ebextensionsを出力するのを忘れてしまうと当然コピーされないのでご注意を。

## nginx.confの準備
そんなわけでincludeされるファイルに記述してもうまくいかないので既存のnginxの設定ファイルに上書きしてしまいます。`server{}`ブロック内に上記のリダイレクト設定を書き込むと以下のようになります。

```nginx
# Elastic Beanstalk Nginx Configuration File

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    33193;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Redirect to https
        if ($http_x_forwarded_proto != 'https') {
           rewrite ^ https://$host$request_uri? permanent;
        }

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }
}
```

上記をコピペして`.ebextensions/nginx/nginx.conf`として保存してやればHTTP→HTTPSリダイレクトが有効になるはずです。
[クイズ]javascriptと仲良くなるための一歩　第１４話「Boolean」

#問題

##第1問

```js
b = true
switch (b) {
  case true:
    "T"
    break;
  case false:
    "F"
    break;
  default:
    "hoge"
}
//=> ?
```

##第2問

```js
b = new Boolean(true)
switch (b) {
  case true:
    "T"
    break;
  case false:
    "F"
    break;
  default:
    "hoge"
}
//=> ?
```

:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:


# 答え

##第1問

```js
b = true
switch (b) {
  case true:
    "T";
    break;
  case false:
    "F";
    break;
  default:
    "hoge";
}
//=> T
```

##第2問

```js
b = new Boolean(true)
switch (b) {
  case true:
    "T";
    break;
  case false:
    "F";
    break;
  default:
    "hoge";
}
//=> "hoge"
```

##ちょっと解説

switch文で隠蔽される同値比較演算は型変換をしない`===`演算である。

```js
b = true
b === true
//=> true

b = Boolean(true)
b == true
//==> true

b = new Boolean(true)
b === true
//=> false
```
Kotlinを用いてAndroid上のデータベースをInsertする

#概要
KotlinがAndroidで公式に対応したとのことで、今後の学習も兼ねて、今更ながらに一部の部品を見直しました。
私自身の為の備忘録を兼ねているため、文章を含めてベストプラクティスではないかもしれません。
#データベース操作
##データ構造
今回はテスト用として

| Name | Type | Primary |
|:-----------|------------:|:------------:|
| id | Integer | 〇 |
| category_id | Integer | × |
| name | Text | × |
というデータを使用していきます。今回はcategoryテーブルについては省略します。
##BuilderによるデータベースInsert文
Builderパターンを用いてデータベースを構築していきます。
以下ModelとBuilderの処理です。

```DatabaseModel.kt
//
class DatabaseModel(private var categoryId: Int, private var name: MutableList<String>) {
    fun getName(): MutableList<String> {
        return name
    }

    fun setName(mName: MutableList<String>) {
        this.name = mName
    }

    fun getCategoryId(): Int {
        return categoryId
    }

    fun setCategoryId(catId: Int) {
        this.categoryId = catId
    }

}
```

どうやらコンストラクタから直接参照できるらしいですが、データ構造が把握しにくいため、フィールドはちゃんと宣言しておいた方がいいかもしれません。

```DatabaseBuilder.kt
class DatabaseBuilder {
    private var listData: MutableList<DBModel>

    init {
        this.createArrayData()
        listData = mutableListOf()
    }

    fun create(categoryId:Int, vararg name: String) {
        listData.add(DatabaseModel(categoryId, mutableListOf(*name)))
    }

    fun createArrayData() {
        this.create(1,"犬", "いぬ")
        this.create(2,"猫", "ねこ")
        this.create(3,"猿", "さる")
        this.create(4,"馬", "うま")
    }

    fun getData() : MutableList<DBModel>{
        return listData
    }
}
```

Kotlinでは、可変長引数は_vararg_で定義します。そこからListに変換するには_mutableListOf(*変数名)_にて変換ができます。

```DatabaseFactory.kt
class DatabaseFactory(mContext: Context) : SQLiteOpenHelper(mContext, DATABASE_NAME, null, DB_VERSION) {
    var builder: DatabaseBuilder

    init {
        builder = DatabaseBuilder()
    }

    //Insert処理
    override fun onCreate(db: SQLiteDatabase) {
        val dbData = builder.getData()
        var id = 0
        try {
            db.execSQL(SQL)

            for (datum in dbData) {
                val categoryId = datum.getCategoryId().toString()

                for (name in datum.getName()) {
                    //CREATE TABLE IF NOT EXISTS data(id integer,category_id integer, name text, primary key(id));
                    val sql = INSERT_SQL    
                    id++
                    db.execSQL(sql, arrayOf(id,categoryId, name))
                }
            }


        } catch (ex: SQLiteException) {
            Log.d(TAG, "SQLite execution failed:" + ex.localizedMessage)
        }
    }
```
データベース登録処理。Javaから変換して触っていない為、改良の余地があるかもしれません。
Volumio2 with Fe-Pi Audio Z v2


## Overview
- `volumio-2.246-2017-07-31-pi.img`, kernel version is 4.9.36 which supports Fe-Pi Audio
-  Modify `dacs.json` (in `/volumio/app/plugins/system_controller/i2s_dacs/`) for Fe-Pi Audio Z
- It seems Only 16bit sampling is supported on Fe-Pi Audio, Turn **Reampling** and force to use 16bit. 



## Environment
- [FE-PI AUDIO Z V2](https://fe-pi.com/products/fe-pi-audio-z-v2) +
    - Raspberry Pi Zero W ,
    - Raspberry Pi Zero + USB  Wifi(8192cu),
    - Raspberry Pi 2 + USB Wifi(8192cu) , or
    - Raspberry Pi 3


## How to:

1. Download Image file
	- [Volumio](https://volumio.org/) - Audiophile Music Player <br>=> [DOWNLOAD](https://volumio.org/get-started/) => RASPBERRY PI 

		```
		Volumio Audiophile Music Player for Raspberry Pi
		VERSION: 2.246
		RELEASE DATE: 31-07-2017
		```
		- Filename: `volumio-2.246-2017-07-31-pi.img.zip`
		- Kernel version: `Linux volumio 4.9.36+ #1015 Thu Jul 6 16:07:57 BST 2017 armv6l GNU/Linux`

2. Burn to microSD
	- Burn tool: [Etcher](https://etcher.io/)

3. Boot

4. Connect to Raspberry Pi directly via Wifi
	- You see SSID: **Volumio**<br>![Qiita-Volumi-01.png](https://qiita-image-store.s3.amazonaws.com/0/75594/ed061f62-4516-6bf8-badb-546376dd7ea4.png)
	- Connect with the default password '`volumio2`'
	- Open WebBrowser and access to http://192.168.211.1/ <br>![Qiita-Volumi-02.png](https://qiita-image-store.s3.amazonaws.com/0/75594/ee5c0565-b883-805c-a4c3-1ecb9a401f22.png)


5. Modification for Fe-Pi Audio
	1. Enable SSH
		- http://192.168.211.1/dev
		- Press `[Enable]` in SSH

	2. ssh login
		- IP: `192.168.211.1`
		- user: `volumio` / password: `volumio`
		- `$ ssh volumio@192.168.211.1`
		- ssh client: [putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)

	3. Modify `dacs.json` and restart volumio.service

		```bash"Copy_And_Paste
		cd /volumio/app/plugins/system_controller/i2s_dacs/
		grep -i 'fe-pi' ./dacs.json >/dev/null || sed -i -e '2a\ \ \ \ {"id":"fe-pi-audio","name":"Fe-Pi Audio","overlay":"fe-pi-audio","alsanum":"1","mixer":"","modules":"","script":"","needsreboot":"yes"},' ./dacs.json
		systemctl restart volumio
		```
6. Settings for Fe-Pi Audio
	1. http://192.168.211.1/
	2. Click the gear icon at the right-top, and choose '**PLAYBACK OPTIONS**'
	3. Change the settings as:
		- Audio Output
			- I2S DAC: **ON**
			- DAC Model Fe-Pi Audio<br>
		- Audio Resampling
			- Audio Resampling: **ON**
			- Target Bit Depth: <font color ='red'>**16**</font> !!!

		and then press <font color='blue'>**[SAVE]**</font> and restart system.

7. Play Music
    1. Copy Music file (*.mp3) to `\\192.168.211.1\Internal Storage\`
    2. Browse => My Library => INTERNAL => ... and click the favorite music ♪♪