OmniAICreator/Qiita-1.07M huggingface dataset:
GoogleMapのMarkerにclickイベントを設定したら、2回呼ばれるので調整

GoogleMapにカスタムのMarkerを設置して、
そのMarkerにクリックイベントを設定したら、どうやら2回クリックイベントが呼ばれている

## 書いたコード
```js
const marker = new google.maps.Marker({
    position: {lat: 35.6894 , lng: 139.6917 },
    icon: `${basePath}img/marker.png`,
    map: map,
});

marker.addListener('click', () => {
    console.log('MarkerClick');
});
```
こうかくと、何故かコンソールには
`MarkerClick` が2回表示される

### なぜ2回呼ばれているのか
```js
marker.addListener('click', ({ domEvent }) => {
    console.log('MarkerClick', domEvent);
});
```
こうすると、コンソール表示は
domEventが、`TouchEvent` と `MouseEvent` が表示されていました
これが原因のようです:sweat_smile:

### もしかして…
動作確認環境よって違う？
`TouchEvent` と `MouseEvent` が表示されていたのは、chromeの開発ツールでモバイル表示
chromeの開発ツールPC表示の場合だと `PointerEvent` のみでした

* iPhone8 iOS15.3.1 safariだと`TouchEvent`のみ
* iPhoneX iOS16.5 safariだと`TouchEvent` と `MouseEvent`
* Android9 chromeだと`TouchEvent` と `MouseEvent`

と端末によっても、ちょっと挙動が違いました・・・
やっかいですね・・・

### ちなみに
イベントタイプは以下のようでした
| domEvent     | type     |
|:------------:|:--------:|
| TouchEvent   | touchend |
| MouseEvent   | click    |
| PointerEvent | click    |


## 書き換えたコード
:whale: ヒントになった公式ドキュメントのページ
https://developers.google.com/maps/documentation/javascript/advanced-markers/overview?hl=ja#make_markers_respond_to_click_and_keyboard_events

なるほど、高度なマーカーのクリックイベント操作ですわ :rolling_eyes:
```js
marker.addListener('click', ({ domEvent }) => {
    if (
        isDesktop && domEvent.type == 'click' ||
        !isDesktop && domEvent.type == 'touchend'
    ) {
        console.log('MarkerClick');
    }
});
```
これで1回しか呼ばれなくなりました
`isDesktop` でデスクトップなのかタッチデバイスか判定しています


## まとめ
特に2回呼ばれていても変な挙動をするようなことは書いていなかったけど
のちのちバグに繋がりそうなので、1回にするべる奮闘したけれど、
今まで得にバグってないので、やらなくても良かったかも？
(リンクだけです)ピクチャーインピクチャー（Picture-in-picture）を調べてみた。

**・「ピクチャーインピクチャー」と「ミニプレーヤー」との違いについて、まとめサイトを探しています。**

**・youtubeの画面上のコマンドについて、PC,タブレット,スマホ毎の違いのまとめサイトを探しています。**


# 「ピクチャーインピクチャー」について

➀常に最前面
＞ PiP は、他のウィンドウの上に浮かぶポップアウト型の常に最前面に表示されるビデオ プレーヤーです。

➁?Windows 11で(画面下の赤い線)「動画の進行状況のバー」が表示されません。
表示されない仕様かもしれません。

# wikipediaで

＞ピクチャーインピクチャー wikipediaの日本語版ありません。
＞Google Translateできます。(Windows)

https://en.wikipedia.org/wiki/Picture-in-picture

# androidで
＞ピクチャ イン ピクチャ モード

https://developer.android.com/about/versions/oreo/android-8.0?hl=ja#opip
オラクルのIDaaS「OCI IAM Identity Domains」とは？

オラクルにIDaaS(Identity as a Service)ってあるの？と思っている方が多くいると思いますが、オラクルは20年以上に渡りID・認証管理領域の製品をリリースしており、そのノウハウをフルに活用したIDaaS「OCI IAM Identity Domains」を提供しています。

今回のはこのオラクルのIDaaSである「OCI IAM Identity Domains」を簡単に紹介します。
※OCI：Oracle Cloud Infrastructure
# OCI IAM Identity Domainsの役割
OCI IAM Identity DomainsはOCIサービスの1つになりますが、まず最初にOCI IAM Identity Domainsの2つの役割を紹介します。

**役割1. OCI管理者・開発者・運用者のID・認証管理 ← OCIのIAM的位置づけ**
　OCIリソースへアクセスする管理者・開発者・運用者のID管理、OCIコンソールアクセスの認証管理を実現します。

**役割2. アプリケーション利用者のID・認証管理 ← IDaaSの位置づけ**
　WebアプリケーションやSaaSを利用する一般ユーザーのID管理・認証管理を行いシングルサインオンや認証強化を実現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470704/1da251cb-2c97-26c7-3f81-190427b5eb6e.png)
一般的には役割1.(OCIのIAM的役割)のイメージが強いと思いますが、OCI IAM Identity Domainsは役割2.(IDaaSの役割)を意識して開発されたサービスになります。

役割2.の場合にはIDaaSの位置づけになるため、OCI上で稼働しているWebアプリケーションに限らず、SaaSや各種クラウド基盤で稼働しているWebアプリケーション、オンプレミス上で稼働しているWebアプリケーションに対する利用者のID・認証管理がもちろん可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470704/f11c3e52-8078-f4fa-f85b-0c8b9a43f629.png)
# OCI IAM Identity Domainsの機能
フェデレーション技術やGateway方式を用いた認証連携機能、MFA(2要素認証)やリスクベース認証などの認証強化関連機能、開発を行うためのREST APIなど役割2.(IDaaSの役割)を意識した機能が豊富に用意されています。
※役割1.(OCIのIAM的役割)でもこれら機能を使うことが可能です。
・認証連携
　　-SAML、OpenID Connect、OAuth
　　-Gateway方式
　　-ソーシャルログイン連携
　　-外部IdP連携
・認証強化
　　-2要素認証(モバイルAuthenticator、FIDO Authenticator、Email、SMS、チャレンジQA)
　　-リスクベース認証
　　-認証強化ポリシー
・ID管理
　　-Web Console、CSV、REST API
　　-SCIM連携
　　-Active Directory連携
・その他
　　-通知
　　-レポート
　　-セルフサービス　などなど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470704/6a1c9eed-d0db-7f71-18d7-806017728d1a.png)
機能の詳細についてはこちら参照：https://speakerdeck.com/oracle4engineer/oci-identity-domains-technical-basic
# OCI IAM Identity Domainsの課金タイプ
OCI IAM Identity Domainsには4つの課金タイプが用意されており、1つのOCI IAM Identity Domainsに1つの課金タイプを適用することになります。
用途(管理したい利用者の種別、認証連携するアプリケーションなど)応じて課金タイプを選択することができます。
　・Freeタイプ
　・Oracle Apps Premiumタイプ
　・Premiumタイプ
　・External Userタイプ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470704/d1469ac0-a7b5-de40-7889-8651d6b1ba37.png)
課金タイプの詳細についてはこちら参照：https://docs.oracle.com/ja-jp/iaas/Content/Identity/sku/overview.htm
# 最後に
OCI IAM Identity Domainsは、今回紹介した機能や課金タイプを活かしてこんな使い方ができるIDaaSだと思います。
　・社内の標準となる認証基盤として使う
　・会員向けECサイトやモバイルアプリケーションの認証基盤として使う
　・社員が使う複数あるSaaS向けの認証基盤として使う
　・自社開発している企業向けパッケージの認証強化(2要素認証)として使う
IDaaSを検討する際の参考になればと思います。
【Cisco_】Smart Licensing Using Policy(オフライン)

IOS-XE 17.3.2 以降の C9000シリーズスイッチでは、Smart Licensing Using Policyと呼ばれる新しい仕組みでのみライセンス管理を実施します。CSSMオフラインの対応方法と注意点について記載します。

CSSM オフライン採用時の注意点
・Ack インポート実施後に write erase を実行して設定を初期化すると、
　再度レポートファイルの出力と ACK の発行・インポートが必要になります。
　Ack インポート実施後は write erase を実行しないことをお勧めします
・機器の時刻が大きくずれている場合、Ack インポート時にエラーとなる場合があります

手順は以下になります。 
1.トランスポートモードの設定 
2.ライセンスレベルの設定（必要に応じて） 
※設定変更後は再起動が必要 
3.レポートファイルの出力 
4.Ack ファイルのインポート 
5.ステータスの確認

1.トランスポートモードの設定 
デフォルトはcsluなのでオフラインに設定変更します。 
コマンドは以下の通りとなります。 
(config)#lisence smart trnansport off

2.ライセンスレベルの設定 
以下のコマンドでライセンスレベルを変更します。 
 
(例)network-essentialの場合を想定 
network-essentialのみ 
(config)#license boot level network-essential 
dna-essentialsも付与する場合 
(config)#license boot level network-essential addon dna-essentials  
 
【注意点】 
・デフォルトではDNAライセンスを使用する設定になっています。 
・ライセンス適用をやり直す必要性が発生する可能性が出るためレポートファイルを出力する前 
   にライセンスレベルの設定を必ず実施してください。 
・ライセンスレベルの設定を実施した際は、再起動しないと設定が反映されません。 

3.レポートファイルの出力
特権モードで以下のコマンドでレポートファイルの出力を実施

license smart save usage all file flash:[任意のファイル名.txt]

※スタック構成で組んだ状態でもライセンス実施に影響はないのでレポート出力してください。
   出力されるレポート内にスタック構成の台数分出力されます。(シリアルナンバーで区別さる)

4.Ack ファイルのインポート
CSSMでライセンス用のAckファイルを取得できたら、
TFTPサーバ等で機器にファイルを転送します。
転送が終えたら以下のコマンドでインポートを実施します。

license smart import flash:<Ack名>

インポートが正常に実施されると「Import Data Successful」と表示されます。

5.ステータスの確認
ステータスの確認は、show license status または show license all の Usage Reporting: 　　　　　　　を確認します。Ack インポート後の表示は以下のようになります。

Usage Reporting:
Last ACK received: Mmm dd hh:mm:ss 2021 JST '←---------★注目★'
Next ACK deadline: Mmm dd hh:mm:ss 2022 JST '←---------★注目★'
Reporting push interval: 30 days
Next ACK push check:
Next report push: Mmm dd hh:mm:ss 2021 JST
Last report push:
Last report file write: Copy

上のように Last ACK received: に Ack インポート実行日時が表示されます。
また、Next ACK deadline: の表示が更新されます。

CSSM オフラインの対応は以上です
Karateを始めよう

# はじめに
自動テストツールも様々あり、どれを使ったらいいのか私自身悩むことがあります
また今まで手動テストばかりやってたけど、自動テストにチャレンジしてみたい方もいらっしゃるかと思います
そこで今回はKarateを使って、環境構築からとりあえず動いた！までの流れを書いていきます
# 前提
Karateのバージョンは1.4.0
# 環境構築
* Javaインストール
Karateは1.4.0からはJava11以降をインストールする必要があります
ローカルPCのOSに合わせて適切なJavaをインストールし、環境構築JAVA_HOMEを設定してください
# Karateダウンロード
Karateには既に動くサンプルプロジェクトがあるのですが、今回はKarateの様々な機能を動作させることができる[karate-todo](https://github.com/karatelabs/karate-todo)を使います
GitHubにアクセスし、ソースコードをダウンロードしてください

https://github.com/karatelabs/karate-todo

※緑色のCodeボタンからZIPをダウンロードしても大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337363/fad72389-7436-c0b9-a1e5-573e92145e7b.png)
# Karateの実行
Karateの実行方法はいくつかありますが、Mavenを使って実行したいと思います
まずはローカルPCのターミナルを起動し、カレントディレクトリをダウンロードしたフォルダに変更してください
次にターミナルで以下のコマンドを実行してください
```
./mvnw clean test -Dtest=ApiTest
```
**BUILD SUCCESS**と表示されたらMavenでKarateの実行完了です

上記のコマンドを解説すると
>* ./mvnw：Maven Wrapperと呼ばれるツールの実行可能ファイルで、MavenのインストールなしにMavenコマンドを実行するための仕組み
>* clean：cleanはビルドをきれいな状態から開始したい場合や、以前のビルドの成果物を削除したい場合に使用
>* test：testはテストの実行、テスト結果のレポート生成などが行われる
>* -Dtest=ApiTest：特定のテストを実行したい場合に指定

簡単に言うと、いったんきれいにして/app/api/ApiTest.javaを実行したというものでして、ApiTest.javaから/app/api/simple/simple.featureに記述されたテストスクリプトを実行したというものになります
※Mavenをインストールしていてば、./mvnwをmvnに置き換えて実行することも可能です
# おわりに
他にも動かし方はあるのですが、これでとりあえず動いた！までが実現できます
Karateは日本語の記事が少ないので、今後も記事を書いていきたいと思います
【Cisco_設定】MEおよび従属APのバージョンアップ

MEに帰属している状態でAPも含めたバージョンアップ時の手順。

【必要なもの】
ME用OSで該当バージョンのZIP(使用時には展開してください)

【手順】
1.MEのGUI画面に入り管理＞ソフトウェアアップデートを表示
2.TFTPモードを選択し、TFTPサーバのIPを入力
3.ファイルパスには、展開した該当のOSフォルダを記載
　(TFTPサーバの設定でOSフォルダを格納しているフォルダを選択)
4.Saveをしたら更新を押下

バージョンアップが開始されます。

下記にバージョンアップを試した際の画面を貼付します。


※AIR-AP1832iで検証
SnowFlake⇨Tableauのロール権限について

# 1.基本的なロールの確認
引用：https://www.youtube.com/watch?v=Ok8kMxl1FdE
![スクリーンショット 2023-06-23 7.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/a80c04f8-92a3-fe54-0cc0-8ccb572cda24.png)


こちらが、デフォルトで作成されているシステム定義ロールになっています。

階層は以下のようになっています
引用：https://docs.snowflake.com/ja/user-guide/security-access-control-overview
![スクリーンショット 2023-06-23 7.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/c8b6a69d-750d-9b57-f924-da0c548e05f0.png)

ACCOUNTADMINが最上位のロールとなっており、基本的にはこれは用いないことが正しいです
そこから細分化され、最終的にはPUBLICロールという自動的に付与される一番権限が低いロールとなっています。

必要に応じて、PUBLICロールから派生させていくことがベストプラクティスとなっています。

# 2.ロールの設定方法
## 今回のユースケース:Tableuでの可視化
DWHからBIツールで可視化というのはよくあるユースケースかと思います。
今回はsnowflake⇨Tableuを使うための最低限のロールを付与していきます。
## ロールの作成
ロールの作成はWorksheat上でSQLコマンドで実行させます
```sql
--ロールの作成
CREATE OR REPLACE ROLE tableu_maneger;
```
これで空のロールが作成されます
このような感じで、実際にロールを割り当てる画面を見てみると確かにロールがあります
![スクリーンショット 2023-06-23 7.57.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/c7b34906-f99d-5b62-fb99-39f0be6bdfd4.png)
## 権限の付与
引き続き権限を付与させていきます

```sql
GRANT USAGE ON DATABASE <データベース名> TO ROLE <与えたいロール名>;
GRANT USAGE ON SCHEMA <データベース名>.<スキーマ名> TO ROLE <与えたいロール名>;
GRANT USAGE ON WAREHOUSE <WAREHOUSE名> TO ROLE <与えたいロール名>;
GRANT SELECT ON TABLE <データベース名>.<スキーマ名>.<テーブル名> TO ROLE <与えたいロール名>;
```
今回は、あるテーブルに対して、読み取ることが最低限です。
特にTableuを使うエンドユーザーはDBに対して書き込みなどは行いません。
そのため、どのDBのどのテーブルのSELECT(読み取り)権限を与えるのか
そして、忘れてはいけないのが、WAREHOUSEの指定です。
WAREHOUSE(コンピューティング)がないとそもそも読み取りすることすらできません。

これらを指定してあげてあとは作ったロールをユーザーに付与していきます。

## ユーザーに権限の付与

```sql
GRANT ROLE <ロール名> TO USER <ユーザー名>;
```
デフォルトロールにしないと、使うユーザーがエラー起きてしまったので、設定しました。
```sql
ALTER USER <ユーザー名> SET DEFAULT_ROLE = <デフォルトロールにしたいロール>;
```

# 3.まとめ
今回はTableauを使えるようにした最低限のロール権限を作成しました。
よかったら使ってみてください。
それでは
初心者のLinux基本

##  はじめに
Linuxを勉強したので自分の学習用記録としてアウトプットしてみました。
今後勉強の継続と共に記事を更新していく予定です。

## 1. 基本情報
- OSの一種でコンピュータを動かすための基本ソフト
- サーバー、デスクトップ、組み込みといった幅広い用途で使われてる
- 特徴
　　　　①オープンソースのため誰でも自由に使える
　　　　②品質の高い多くのソフトウェアが利用できる
- 欠点
　　　　　①商用アプリケーション(Microsoft Office等)があまり存在しない
　　　　　②日本語対応されいない部分が多い

## 2.なぜLinuxを学ぶのか
- 幅広い場所で使われている
  サーバー用や組み込み器用と幅広い場所でマシンを操作するのに必要
　　　　web業界の約90%のサーバーはLinuxを使用
- 長年使える
**linuxは一度習得すると何年経っても使える技術である！**

## 3.Linux ディストリビューション
`カーネル`：OSの中核となるソフトウェア

:::note warn
カーネルだけでは実用的ではないためその他のソフトウェアが必要
:::

`ディストリビューション`：カーネルに色々なソフトウェアを組み合わせて使いやすくしたもの
-Red Hat系とDebian系が主流
**Red Hat系**  　　centOS 無償で手に入り利用者が多く情報も豊富

## 4.シェルについて
シェルはLinuxのCLI(キーボードからコマンドを入力し文字列として結果を出力するインターフェイス)を提供するソフトウェア。ユーザーとLinuxカーネルの仲介役(カーネルのインターフェイス)をしている
**Linuxの操作は基本コマンドから行う。そのコマンドを入力する場所がシェル**
`$`：プロンプト

:::note warn
ターミナル：入出力の画面を提供するソフトウェアのこと
**ターミナルとシェルは別物でターミナルの中でシェルが動いている！！！**
:::

### シェルの種類
`sh`:もっとの古いシェルでほぼ全てのUnixで使用できるが機能は少ない
`bash`:shを基本として機能を拡張したシェルで学習として使用するのにオススメ！
`zsh`:bashの機能を取り込み、独自の拡張も追加。機能も豊富 

### シェルの便利機能
1.カーソルの移動
|コマンド|内容|
|:----|:---|
|⌘+f|一文字次へ移動|
|⌘+b|一文字前へ移動|
|⌘+a|行の先頭へ移動|
|⌘+e|業の最後に移動|
|esc+f|一単語次へ移動|
|esc+b|一単語前へ移動|

2.文字列の編集
|コマンド|内容|
|:---:|:--|
|⌘+h|カーソルの左を一文字削除|
|⌘+d|カーソル部分を一文字削除|
|⌘+w|カーソル位置の単語を削除(カーソルの前部分)|
|⌘+u|カーソルの位置から行頭まで削除|
|⌘＋k|カーソル位置から行末まで削除|
|⌘+y|最後に削除した内容を挿入|

3.トラブル時の対応
|コマンド|内容|
|:---:|:--:|
|⌘+c|実行中のコマンドを強制終了|
|⌘+l|画面の消去。文字化けした時のクリアにも使える|
|⌘+s|画面表示のロック(キーボードから文字の入力を受け付けない)|
|⌘+q|画面表示のロックの解除|

4.補完・コマンド履歴
|コマンド|内容|
|:---:|:--:|
|Tab|コマンドやパスの補完|
|⌘+p　または↑|ひとつ前の履歴を見る|
|⌘+n または↓|１つ後ろの履歴を見る|
|⌘+r|コマンド履歴のインクリメンタル検索|
|文字の入力|コマンド履歴から検索|
|⌘+r|一つ前の検索結果へ移動|
|enterキー|現在の検索結果を実行|
|escキー|現在の検索結果を表示したままコマンドラインへ戻る|
|⌘+g|検索結果を破棄しコマンドラインに戻る|

## 5. ディレクトリの構造
ディレクトリはファイルが保管されている場所のこと

:::note
一番上の「/」をルートディレクトリという
:::

### 主要なディレクトリの役割
`/bin`
一般ユーザー及び管理ユーザーの両方が使用するコマンドの実行ファイルを格納  
特にLinuxの動作に最低限必要な重要度の高いコマンドの実行ファイルを格納
`/dev`
デバイスファイル（ハードウェアをファイルとして扱えるようにしたファイル）を格納
`/etc`
設定ファイルを格納。　Linuxで動作するアプリケーションの設定ファイルや、Linux自体の設定に関わるファイルが置かれる
`/home`
ホームディレクトリが配置される。ユーザーはホームディレクトリ内に自由にファイルやディレクトリを作成できる
【Cisco_障害】アップリンク障害時対策の設定(UDLD)

UDLDとは単一方向リンクを検出することができるL2プロトコルです。

一方の機器でトラフィックを送信できるが受信できない、もう一方の機器でトラフィックを受信できるが送信できない状態のことです。UDLDにより、光ファイバーまたはUTPケーブルで接続されたデバイスがケーブルの状態をモニターして、単一方向リンクを検出すると設定対象ポートをシャットダウンできます。

L2ループが発生しそうになっても、UDLDで単一方向リンクを
検出して該当ポートをシャットダウン（ err-disabled ）にすることから、そのような問題を回避できます。

![UDLD障害.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350668/48237a25-2f48-0a53-d405-14c4e02ebdcb.png)

上図の状態になるとL2ループが発生する恐れがあるので、UDLDの設定を以下のコマンドで任意に設定

機器上でUDLDを有効化する。　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　(config)udld enable ｜ aggressive

ポート単位で設定する　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　(config-if)udld port aggressive     もしくは　udld aggressive
Android、kotlinでViewBindingがエラーになる

# 今日からViewBindingがエラーになる・・・？
今まで普通にViewBinding使えていたのに、今日、新規プロジェクトを作成するとViewBindingがエラーになる。kotlinソース的には何も変わらないのに・・・

```groovy:build.gradle
android {
    ・・・
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = '17'
    }
    viewBinding {
        enabled = true
    }
    ・・・
}
```
```kotlin
binding = ActivityMainBinding.inflate(layoutInflater)
```
```
Error in ViewBinding in Kotlin, Error is to check module classpath for missing or conflicting dependancies
```
[stackOverFlow](https://stackoverflow.com/questions/71139061/error-in-viewbinding-in-kotlin-error-is-to-check-module-classpath-for-missing-o)にも情報があった。

以前に作ったプロジェクトと比較するとgradle.propertiesに差異がある。
```diff_properties:gradle.properties
- android.defaults.buildfeatures.buildconfig=true
- android.nonFinalResIds=false
```
この2行がない。この辺の新規プロジェクトで作成される雛形はAndroidStudioをアップデートすると結構頻繁に変わる。

上の2行を追加してgradleを同期。出たくなった。
試しにまた削除して、gradleを同期。エラーが出ない？？！！

この2行は何なのか？[AGP（Android Gradle Plugin）8.0に関係しているらしい。](https://developer.android.com/build/releases/gradle-plugin#default-changes)
* android.defaults.buildfeatures.buildconfig
   * AGP 8.0 は、デフォルトでは BuildConfig を生成しません。このオプションは、必要なプロジェクトで DSL を使用して指定する必要があります。
* android.nonFinalResIds
   * AGP 8.0 は、デフォルトで非最終フィールドを持つ R クラスを生成します。

**なーんか、ちょっと釈然としないんだけど・・・**
どなたか、この辺の事情に詳しい方、解説お願いします。
AWS CLIでRoute53のHosted ZoneにサブドメインのNSレコードを登録しよう

# はじめに
AWS CLIを利用して、Route53のHosted ZoneにサブドメインのNSレコードを登録する。
GitHub Actionsでも利用できるように、シェルスクリプトで作成する。

# スクリプト

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

set -e

if [ $# != 2 ] || [ $1 = "" ] || [ $2 = "" ]; then
  echo -e "Two parameters are required

  1st - string: Hosted Domain Name on Route 53 (e.g. example.com)
  2nd - string: Subdomain Name (e.g. sub.mexample.com)

  example command
  \t sh ./add_ns.sh example.com sub.example.com"
  exit
fi

HOSTED_DOMAIN=$1
TARGET_DOMAIN=$2

echo -e "\t HOSTED_DOMAIN = ${HOSTED_DOMAIN}"
echo -e "\t TARGET_DOMAIN = ${TARGET_DOMAIN}"

RECORD_SET_ID_HOSTED_DOMAIN=$( \
  aws route53 list-hosted-zones \
  --query "HostedZones[?Name=='${HOSTED_DOMAIN}.'].Id" \
  --output text) \
&& echo -e "\t RECORD_SET_ID_HOSTED_DOMAIN = ${RECORD_SET_ID_HOSTED_DOMAIN}"

RECORD_SET_ID_TARGET_DOMAIN=$( \
  aws route53 list-hosted-zones \
  --query "HostedZones[?Name=='${TARGET_DOMAIN}.'].Id" \
  --output text) \
&& echo -e "\t RECORD_SET_ID_TARGET_DOMAIN = ${RECORD_SET_ID_TARGET_DOMAIN}"

IS_RECORD_SET=$( \
  aws route53 list-resource-record-sets \
  --hosted-zone-id ${RECORD_SET_ID_HOSTED_DOMAIN} \
  --query "ResourceRecordSets[?Name=='${TARGET_DOMAIN}.'].Name" \
  --output text \
  | wc -w) \
&& echo -e "\t IS_RECORD_SET = ${IS_RECORD_SET}"

if [ ${IS_RECORD_SET} != 0 ]; then
  echo -e  "\t it already exists"
else
  RECORDS=$( \
    aws route53 list-resource-record-sets \
    --hosted-zone-id ${RECORD_SET_ID_TARGET_DOMAIN} \
    --query "ResourceRecordSets[?Type=='NS'].ResourceRecords[]") \
  && echo -e "\t RECORDS = ${RECORDS}"

  CHANGE_ID=$( \
    aws route53 change-resource-record-sets \
    --hosted-zone-id ${RECORD_SET_ID_HOSTED_DOMAIN} \
    --change-batch \
    "{
      \"Changes\": [
        {
          \"Action\": \"CREATE\",
          \"ResourceRecordSet\": {
            \"Name\": \"${TARGET_DOMAIN}\",
            \"Type\": \"NS\",
            \"TTL\": 300,
            \"ResourceRecords\": ${RECORDS}
          }
        }
      ]
    }" \
    --query "ChangeInfo.Id" \
    --output text) \
  && echo -e "\t Change ID : ${CHANGE_ID}\n"
fi
```
はてなブックマークの活用のすゝめ

## はてなブックマークとは

以下はてブと訳す。いわゆるソーシャルブックマークサービスで、どのドメインの記事であろうが、twitterであろうがtiktokであろうが、コメント付きでブックマークできるサービス。そのコンテンツを投稿した人がはてブを知らない場合、その投稿者のあずかり知らないところでディスり、けなし、またある時は上から目線で評価し、神の視点から評論家を気取ることができるサービスである。
この辺のクエリを読むとといい
[google.com/search?q=はてなブックマーク活用](https://www.google.com/search?q=%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E6%B4%BB%E7%94%A8)

## なぜはてブを使うといいのか

まずシニアエンジニア層が使ってることが多い。はてブはITカテゴリ問わず活用されているが、特にITカテゴリで20ブックマーク以上ついているものは良質な最新情報であったりとか、実際に技術選定をどのように行ったか、エンジニア組織の改善などとてもためになるものが多い。

リアルタイムに追う場合と、後から検索に使う場合両方とても活用できて、リアルタイムに追う場合は最新情報のキャッチアップ、後から検索に使う場合は世の中的に正しいとされているベストプラクティスであったり、似ている技術の比較など技術選定に活用することができる。

またそういう性質上、コメント欄がとても勉強になるし、例えばセキュリティ的に問題があるような実装を平然と記事に書いていると強烈なまさかりがもらえたりする。

特に拡張機能を入れておくと、検索結果にもブックマーク数が表示されるようになり、ある程度多くの人の視線に触れてその批評を耐えた記事かどうかが読む前にある程度判断できる。というか拡張機能なしだと半分のバリューぐらいしかはっきしないと思う。

https://chrome.google.com/webstore/detail/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF/dnlfpnhinnjdgmjfpccajboogcjocdla?hl=ja

![Screen Shot 2023-06-23 at 16.44.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/df4da4e4-c2db-ca00-33ca-ad1704b805fe.png)
この辺のブックマークの付き具合でどのくらい有名な技術なのかもわかる。

![Screen Shot 2023-06-23 at 16.45.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/34f7bf14-dd92-6988-ce9d-985f9718e5d0.png)
最初のブックマークがいつついたのかなどを見ると、その技術がいつ出て今にかけてどういう評価の変遷を辿ってきたのかなどわかる。

## 具体的な活用事例

最近だとserverless frameworkに詳しくないのでこの辺のクエリで調べたところ、serverless frameworkはcloudformationベースで作られていてデプロイが遅く、言わずと知れたterraformとlambrollというlambdaのcdに特化したツールに乗り換えたという記事が出てきてとてもためになった。

[https://b.hatena.ne.jp/q/serverless%20framework?sort=recent&safe=on&target=title&users=20&date_range=5y](https://b.hatena.ne.jp/q/serverless%20framework?sort=recent&safe=on&target=title&users=20&date_range=5y)

![Screen Shot 2023-06-23 at 16.32.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/5f7ca202-d1c0-3670-eee6-267a421fb8a2.png)

## 使わなかった場合の不都合
世の中的なベストプラクティスであったりとか、技術選定の成功失敗事例などを知らない状態で推し進めることになる。特にこの辺はChatGPTはあまり強くないところだと思うので、まだはてブを使うことに軍配が上がる。

## 具体的な使い方

検索ワードがタイトルのみに出てくる記事か、本文に出てくる記事か、それともタグづけされている記事かを選ぶことができる。タイトルのみに絞ると特にその検索ワードについて専門的に書かれた記事が見つかる。

基本的に新しい記事がいいので、人気より新着を選ぶ

ブックマーク数は選択肢がちょっと微妙で検索クエリ欄から直接users=20などに変えて使うことが多い

## すぐに使い始める方法

alfredやraycastなどのランチャーツールにショートカットを設定しておくのがおすすめ。わたしの場合は、左のcmdと右のcmd同時押しでalfredが起動し、`h {keyword}`ではてブ検索ができるようにしてある。

![Screen Shot 2023-06-23 at 16.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/de9225c1-9fa5-ce25-d642-f886d4145d3b.png)

## その他伝えたいこと

弊社CryptoGamesの場合、わたし個人の酔狂によって、ブックマーク数が20以上ついたものをリアルタイムに通知するようにしてある。偉そうなことは言えない立場ではあると重々承知な上であえて偉そうなことを言わせてもらうと、最初は読めないかもしれないが、はてブトレンドを見て実務に活用ができるようになって初めて、ジュニアエンジニアを卒業したといえると思っているのでぜひ活用してほしい。

以上。
Docker環境のmysqlで日本語入力ができないときの対処法

# 記事を書くきっかけ
ローカルの開発環境をDockerで構築後、早速生成したテーブルにデータを登録しようとしたところ、日本語の情報が登録されない。
また、手入力ができない（Enterを押すと日本語が消えてしまう）状態になっていた。

```
$ docker-compose exec db bash

$ mysql -u root -p myapp

Enter password:****

mysql> 日本語 /*←Enterを押すと文字が消えてしまう。すなわち日本語の入力ができない*/
```
# 原因と対処法
mysqlが以下の状態であることが原因である。
- databaseの文字コードが対応していない
- 日本語環境を追加していない

今回はDockerで環境構築をしているため、DB用のDockerfileに上記の設定を追加する。

# 修正後の各種設定ファイル
- Dockerfile
```Dockerfile
ARG MYSQL_VERSION=8
FROM mysql:${MYSQL_VERSION}-debian

COPY my.cnf /etc/mysql/conf.d/my.cnf

# 日本語環境を追加
RUN apt-get update && apt-get install -y locales \
    && sed -i -e 's/# \(ja_JP.UTF-8\)/\1/' /etc/locale.gen \
    && locale-gen \
    && update-locale LANG=ja_JP.UTF-8

ENV LANG=ja_JP.UTF-8
# ここまで

CMD ["mysqld"]

```
- docker-compose.yml
```docker-compose.yml
  db:
    build: db　# 上記Dockerfileの存在するパスを指定
    image: mysql:latest
    command: --default-authentication-plugin=mysql_native_password
```

### 解説

- **apt-get update** パッケージ管理のapt-getに必要な情報を取得
- **apt-get install -y locales** locales（多国語サポート用ライブラリ。日本語を扱うために必要なもの）インストール
- **sed -i -E ‘s/# (ja_JP.UTF-8)/\1/’ /etc/locale.gen** locale.gen上のja_JP.UTF-8がデフォルトでコメントアウトされているので、コメントアウトを解除する
- **locale-gen**  localedef（localesの環境変数の定義のファイルを変更するコマンド）を呼び出すシェルスクリプト。
- **update-locale LANG=ja_JP.UTF-8** localesの環境変数をja_JP.UTF-8に設定する。
- **ENV LANG=ja_JP.UTF-8** ja_JP.UTF-8 を利用する宣言をする

# 参考
https://qiita.com/tomo__x_/items/bd5d86d5f423f8f89b22
https://qiita.com/sun33/items/398479ba586e39dcee13
Trivy アクションの結果をマークダウン形式にフォーマットする

# これは何
コンテナイメージの脆弱性チェックで trivy のお世話になってます。
github workflow の STEP_SUMMARY が便利なので、trivy の結果をそこに出力したい。

trivy アクションの template を指定すれば、マークダウン形式にも対応しそう →　テンプレートが見つからない。

仕方ないので、自力でテンプレートを書く。

なお、trivy にはこんな感じで指定すれば良い
```yaml
  format: template
  template: "@.github/workflows/github-markdown.tpl"
  output: trivy.md
```

## Github workflow

trivy 部分を抜粋

```yaml
  # trivy のためのキャッシュを準備する
  - uses: actions/cache@v3
    with:
      path: .trivy
      key: ${{ runner.os }}-trivy-${{ github.workflow }}-${{ github.run_id }}
      restore-keys: |
        ${{ runner.os }}-trivy-${{ github.workflow }}-
        ${{ runner.os }}-trivy-

  # trivy を使用してイメージの脆弱性を検査する
  - name: Run Trivy vulnerability scanner
    uses: aquasecurity/trivy-action@master
    with:
      scan-type: image
      image-ref: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:test
      vuln-type: os,library
      format: template
      template: "@.github/workflows/github-markdown.tpl"
      output: trivy.md
      ignore-unfixed: true
      severity: CRITICAL,HIGH
      cache-dir: .trivy

  # 検査結果のマークダウンをワークフローの STEP_SUMMARY に吐き出す
  - run: cat trivy.md >> $GITHUB_STEP_SUMMARY
    if: always()

  # trivy のキャッシュのオーナーを補正する
  - name: Correct Trivy cache permissions
    run: sudo chown -R $USER:$GROUP .trivy
```

## マークダウン用 テンプレート

同じ PkgName なら記載しない、という小技を入れている

.github/workflows/github-markdown.tpl
```
{{$d := dict "CRITICAL" "🔴" "HIGH" "🟠" "MEDIUM" "🟡" "UNKNOWN" "🟤" }}

{{- range . -}}
## {{ .Target }}

### {{ .Type }}

{{- $prev := "" }}
{{- range $i, $v := .Vulnerabilities }}
{{- if eq 0 $i }}
| Library | Vulnerability | Fixed Version | Title |
|---------|---------------|---------------|-------|
{{- end }}
{{- with $v }}
{{- $new := ne .PkgName $prev }}
| {{ if $new }}{{ .PkgName }}<br/>{{ .InstalledVersion }}{{ end -}}
| {{ get $d .Vulnerability.Severity }} {{ .VulnerabilityID -}}
| {{ .FixedVersion -}}
| {{ escapeXML .Title -}}
|
{{- $prev = .PkgName }}
{{- end }}
{{- end }}

{{ range $i, $v := .Misconfigurations }}
{{- if eq 0 $i }}
| Type | Vulnerability | Title |
|------|---------------|-------|
{{- end }}
{{- with $v }}
| {{ .Type -}}
| {{ get $d .Severity }} {{ .ID -}}
| {{ escapeXML .Title -}}
|
{{- end }}
{{- end }}

{{- end }}
```


## 結果

STEP_SUMMARY　には、こんな感じで出力される

![スクリーンショット_2023-06-23_16_06_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69410/5ee24508-51a9-fdbc-89df-60c534a04390.png)


## 残課題
 - 設定ファイルチェックのマークダウン化は力尽きた。。
   →　デフォルトの出力形式が一番良さそう。
DockerでRails環境構築

![スクリーンショット 2023-06-23 162947.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341105/b34e9dd4-7f81-2258-bfc1-95ed1b038728.png)
フォルダ内構造は画像の通り
docker-compose.yaml
Dockerfile
srcフォルダ内にGemfile

Gemfile
```
source 'https://rubygems.org'
gem 'rails', '~> 7.0.4'
```

Dockerfile
```
FROM ruby:3.1
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

```

docker-compose.yaml
```
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
```

## Dockerfileのあるディレクトリ内で以下コマンド
### rails 雛形作成
```
docker compose run web rails new . --force --database=mysql
```
### ファイル修正 src\config\database.yml
password: password
host: db
```
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
```
### 再度イメージ作成
```
docker compose build
```
### データベース作成
```
docker compose run web rails db:create
```
### コンテナ作成
```
docker compose up -d
```

## 完成
あとは以下で操作&削除
### コンテナ内に入る
```
docker compose exec web /bin/bash
```
### コンテナ削除
```
docker compose down
```
php:8.2-fpmのdocker imageでapt-getしたらエラーが出まくった

一時的なものかと思いますが忘備録として・・・

# 事象
事象としてはこれです

https://github.com/docker-library/php/issues/1417

docker imageの中で
```
RUN apt-get update && apt-get -y install hoge moge fuga
```

ってしたら

```
Reading package lists...
W: GPG error: http://deb.debian.org/debian bookworm InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY F8D2585B8783D481
E: The repository 'http://deb.debian.org/debian bookworm InRelease' is not signed.
W: GPG error: http://deb.debian.org/debian bookworm-updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY 6ED0E7B82643E131
E: The repository 'http://deb.debian.org/debian bookworm-updates InRelease' is not signed.
W: GPG error: http://deb.debian.org/debian-security bookworm-security InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 54404762BBB6E853 NO_PUBKEY BDE6D2B9216EC7A8
E: The repository 'http://deb.debian.org/debian-security bookworm-security InRelease' is not signed.
E: Problem executing scripts APT::Update::Post-Invoke 'rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true'
E: Sub-process returned an error code
```

エラーが出まくってbuildが通らないって状態です

# 原因
phpのimageでdebianの更新がありました
https://github.com/docker-library/official-images/commit/c89c5a02bcb9afca6f5d8676849c54dc627bbca7

バージョンが `bullseye(11系)` -> `bookworm(12系)` に更新されてaptが通らなくなったみたいです

※Debianのバージョンについてはこちら
https://www.debian.org/releases/index.en.html

# 解決方法
ここに書いてありました
https://github.com/docker-library/php/issues/1417#issuecomment-1591841905

debianをベースとしたphpのdocker imageは、debianのバージョンを指定出来るタグがあります

https://hub.docker.com/_/php

※該当箇所の抜粋
```
Image Variants
The php images come in many flavors, each designed for a specific use case.

Some of these tags may have names like bookworm, bullseye, or buster in them. These are the suite code names for releases of Debian and indicate which release the image is based on. If your image needs to install any additional packages beyond what comes with the image, you'll likely want to specify one of these explicitly to minimize breakage when there are new releases of Debian.
```

なので、 `php:8.2-fpm` -> `php:8.2-fpm-bullseye` で解消されました

# まとめ
- issueの確認を速やかに出来て良かった
- っていうかissueに解決方法が載っているんだからしっかり読めば暫定対応はすぐできたな
    - 解決までに半日ぐらい調べものした
- とは言え、事象の原因も解決方法もちゃんと理解出来たから良かった
- とりあえずこれ怖い・・・
ターミナル上からVSCodeを開くようにするための手順

# 初期設定
## 1. VSCode上でコマンドパレットを開く
パレットは以下のキーを押すと開きます。
```:キー
command + shift + P
```
またはVSCodeの左下にある管理ボタンからコマンドパレットを開くことができます。
<br>

**サンプル画像**
![スクリーンショット 2023-06-23 14.21.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/ca337c1d-fea8-9fe1-d870-5b82f55a6317.png)

## 2. コマンドパレット上でコマンドを入力し、設定項目を選択する
Shellと入力すれば、以下の選択肢があるので選択します。
```
Shell Command: install 'code' command in PATH
```
<br>

**サンプル画像**
![スクリーンショット 2023-06-23 14.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d39103c8-3d7e-81f3-e26f-7b01c6ccbdb0.png)

# 開く手順
## 1. プロジェクトフォルダへ移動する
開きたいフォルダへ移動します。
<br>

**サンプル画像**
![スクリーンショット 2023-06-23 14.12.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/737fc1c8-1e4d-3e24-1b5d-2817aefd99a1.png)

## 2. "code ."を入力する
そのまま、以下のコマンドを実行すれば、VSCodeが立ち上がります。
```:コマンド
code .
```
<br>

**サンプル画像**
![スクリーンショット 2023-06-23 14.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/606f1442-a416-f10b-dc86-25b692764516.png)

# 環境
- OS： macOS Ventura 13.4.1
- VSCode: 1.79.2 (Universal)
- ターミナル: 447

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。
APIの重要さを理解する上でキーとなる「抽象化」の概念

[Postman](https://www.postman.com)が公開している「APIファーストの世界」というコミックがあります。こちらのサイトで無料で閲覧することができます。

https://api-first-world.com/ja/

このコミックでは、Postman創業者のアビナフ・アシュタナが、「APIとは何か」「今のAPIの課題は」「PostmanはAPIファーストの世界を目指して何に取り組んでいるのか」というトピックについて語りかけます。現在、私たちのチームはこのコミックの日本語化を進めていて、まもなくご覧いただけるようになる予定ですが、本記事ではその中から、APIの重要さを理解する上でキーとなる「抽象化」の概念について取り上げてみたいと思います。

**[2023年8月18日更新] コミックの日本語版が公開されました！**

# 物事を抽象化するAPI

次のページでアビナフは、**「APIがユニークな点は、APIを使うことで開発者は物事を抽象化できるところだ」** と述べています。これは、APIを積極的に使うべき大きな根拠になっています。
![API-First-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32610/042a5abe-192a-8d61-03b1-6f7cee41d6d2.jpeg)

では、抽象化とは何のことを指しているのでしょうか。続けて彼はこう説明します。**「抽象化とは、複雑な物事を包み込んでシンプルに見せることを助けてくれる考え方のことだよ」**。つまり、抽象化を行うことで、物事に対する見方がシンプルになり、より複雑なことを考えやすくなる、ということを言っています。

一つ例を挙げてみましょう。あなたはイタリアンレストランを訪れて、何か美味しい料理を食べたいなと思います。メニューを見てカルボナーラを見つけて、これを食べようと決めます。ここで、あなたはカルボナーラの材料や、食材の準備、レシピや調理器具について気にかけることはありません。カルボナーラと注文すれば、15分後には世の中で一般的に認知されているカルボナーラという料理がテーブルに運ばれてくることを期待します。

これは、カルボナーラの注文を受けて調理して提供する、という一連の物事が抽象化されているために実現しています。レストランの客はメニューの品を選べばそれが食べられるということがわかっているので、それがどのように作られるのかは気にせず、レストランでは連れとの会話を食事をしながら楽しめるようになっています（味は気にするかもしれないですけどね！）。

上の例をAPIに当てはめてみると、APIはメニュー、その背後に包み込まれている物事はキッチンで行われている調理もろもろ、そしてAPIの呼び出しは料理の注文、と見ることができるでしょう。

# コンピュータの歴史と抽象化

そしてアビナフはこう続けます。**「この数十年、コンピューティングの世界では、段階的に高次の抽象化を実現するための技術開発に力が注がれてきたんだ」**。実は、コンピュータの進化の歴史は抽象化の歴史と言ってもいいくらい、抽象化の考え方を中心に進んできました。
![API-First-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32610/87e346c1-6a33-9c34-16ef-ff168bcdd02e.jpeg)
コンピュータの黎明期、今でいうプログラムは物理的な回路の実装そのものでした。しかし、これだとほんのわずかなロジックの変更でも、もう一度回路の作り直しになります。その度に新しい基盤や素子が必要になり、お金と時間がかかります。

そこで技術者たちは、メモリ素子に格納されるバイナリデータでロジックを表現することで、バイナリデータを書き換えるだけで動作を変えることを試みます。物理的な回路は汎用的に作っておけば、ロジックを設計する際には物理的な回路を意識せずに済むようになります。第一段の抽象化のできあがりです。

ところで、バイナリデータは0と1の並びですので、人間がこれを見て動作を理解することは困難です。そこで、この数値の並びに人間が理解しやすいシンボルを割り当てることにしました。実装するロジックは、少し言語っぽい要素が入った機械語で記述できるようになります。第二段の抽象化です。

バイナリと機械語の関係はほぼ1対1の関係でしたが、複雑なロジックを記載するにはもっともっとシンプルに、人間の考え方により近い表現でロジックを記述することが求められるようになります。そしてこれを実現するために、様々なプログラミング言語が発明されました。第三段の抽象化です。

そして今、私たちは次の抽象化の段階に進んできています。モバイルデバイスを通じて、私たちは日常どこでもサービスの恩恵を受けるようになりました。プログラムは一箇所ではなく、ネットワークをまたいでロジックが分散した状態で動いています。大量の計算が必要な処理は、クラウド環境で動くようになってきています。これらのIT技術の進化と同時に、新たに必要になった抽象化の手段、それがAPIです。

# APIによる抽象化がもたらす未来

APIによる抽象化が進んでいる今、これまでのソフトウェアの部品、ライブラリなどは徐々にAPIサービスという形での提供にシフトしてきています。アプリケーションの構築は、どのAPIを選択し、どのように組み合わせるか、ということに焦点が移ってくるはずです。コーディングの割合は徐々に下がっていき、ローコード・ノーコードツールを使ったサービス構築が主流になる可能性があります。

昨今注目を集めている生成系AIの登場、そしてAIの外部連携APIの対応もこの流れを後押ししています。既存の情報システムがAIと接続されることで、無限の可能性が開かれつつある状況に皆さんも驚かれていることでしょう。

パラダイムシフトといってもいいこの大きな変化の中、APIがもたらす素晴らしい未来に期待しましょう！
【Cisco_EEM】ポートのDownログから特定のポートをシャットダウンさせる

interface GigabitEthernet0/9のDownログ出力から自動的にポートをシャットダウンおよび
任意のインターフェイスをUPを自動的に実施

event manager applet SHUTDOWN-Gi9
event syslog pattern "Interface GigabitEthernet0/9, changed state to down"
action 1.0 cli command "enable"
action 2.0 cli command "configure terminal"
action 3.0 cli command "interface GigabitEthernet0/9"
action 4.0 cli command "shutdown"
action 5.0 cli command "interface GigabitEthernet0/10"
action 6.0 cli command "no shut"
action 7.0 cli command "end"
action 8.0 cli command "wr"

event syslog patternの記述の後にトリガーにしたいログを設定する。

トリガーがログに出力された後の動きをaction 1.0 cli commandで定義する
NTPサーバー、UDPとは

```NTP(Network Time Protocol)```というプロトコルを利用しています。
トラブルが発生した時にもっとも```重要となる情報が時刻```です。
サーバーやネットワーク機器の時刻がずれていると、```発生した事象を時系列に並べることができず、情報が整理できなくなります```。

# NTPサーバーはUDPを使用している。
### UDPとは？
トランスポート層のプロトコル。
信頼性よりも速度を重視したもので、データが相手に届いたかという確認を行わない。
### 出典
https://gihyo.jp/book/2022/978-4-297-12375-8

# NTPサーバーは階層構造になっている
```ストレイタム(stratum)```という値を使用した階層構造になっている。
最上位はStratum0で原子時計（セシウム時計)やGPS、標準時計など、絶対にずれることのない正確な時刻源です。
階層を降りるごとにStratum１、Stratum2と数字が大きくなります。
Stratum０のサーバー以外のNTPサーバー上位ストレイタムのNTPサーバーに対するNTPクライアントでもあります。そして、上位のNTPサーバーと時刻が同期できない限り、下位のサーバーに時刻を配信しないような作りになっています。

## 気づき
NTPのおかげで時系列を基にした問題解決ができるのか。
UDPを使用して速度を重視してずれないようにしているのか。
時間がずれないように工夫がされているのか。

# 出典
https://www.sbcr.jp/product/4797386660/
【Cisco_ログ取得】隣接機器のデバイス情報取得

直接接続の隣接機器のデバイス情報(型番、製造番号、シリアルナンバー)などが以下のコマンドで表示されます。
show cdp関連コマンドもあるが、CDPの有効かなど条件があるため使用できなことがあるためそういった場面で使用してみるとよい。

●show pnp topology
Neighbor (3): [隣接機器のホスト名], Name:[GigabitEthernet1/0/1], Short Name:[Gi1/0/1], Port ID:[GigabitEthernet0]
Platform:[cisco C9120AXI-Q], Local mac address:[MACアドレス], Remote mac addr:[MACアドレス]
Version:[Cisco AP Software, ap1g7-k9w8 Version: 17.6.3.33
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 2014-2015 by Cisco Systems, Inc.]
UDI:[PID:C9120AXI-Q,VID:V05,SN:[シリアルナンバー]]
社内で「GitでPullRequestする為に​最低限知っておきたい事」ってお題でgitの説明会を開催した

その際の資料を転記します

なお、下を前提としています
* ある程度ターミナルに慣れている
* ある程度技術的素養がある


## gitとは
* バージョン管理システム​
  * 変更履歴の記録​
  * 以前の状態に戻れる​
  * 誰がいつどう変更したか調べられる​
  * ディレクトリの構造全体を記録できる​
* バージョン管理システムのデファクトスタンダードになっている​
* 元はLinuxのコード管理としてLinus氏が開発​
* メンテナは日本人である濱野 純さん​
* 従来の主流であったSubversionが集中型リポジトリでサーバー側で一元管理していたが、その欠点（遅い、マージが大変）への対応として、分散型リポジトリ（開発者のローカルとサーバーがそれぞれ独立している）方式を採用​
* sha1

## git用語集

| # | 用語 | 説明 |
|:-:|:-|:-|
|  1 |  リポジトリ | gitで管理しているファイル群置き場​  |
|  2 |  ブランチ（branch​） |  これまでのファイルの変更履歴から、新たな変更履歴の作成するための枝分かれ​。元々のファイル群に影響する事なく、変更を加えられる​。新規機能の作成やバグ修正のためのパッチ用等​ |
|  3 | マージ​(merge)  |  今自分がいるブランチに他のブランチの変更内容を加えること​。たまにcomflictする（同じファイルの同じところに両者で変更を加えた場合にどちらが正しいのか判断できず、人の手によるマージ作業が必要となる）​ |
|  4 | インデックス/​ステージング​  |  commitする前の一時ファイル置き場​。複数ファイルcommitする場合に一度インデックスにおいて(add)、commitするファイル群を整理してからcommitする​ |


## 知っておくべきコマンド
(説明しながら、ファイルに変更して、どんなレスポンスなのかデモをしていました)

| # | (サブ)コマンド | 作用内容 |
|:-:|:-|:-|
| 1  |  status | リポジトリのファイル変更状況を知る​  |
| 2  | diff​  |  ファイルの差分を確認​ |
| 3  | log​  |  commitの履歴を確認​ |
| 4  |  add |  変更したファイルをステージに登録​ |
| 5  |  commit |  ステージに登録したファイル変更を確定​ |
| 6  | clone  |  リモートのリポジトリをローカルにコピー​ |
| 7  | branch  |  リポジトリのブランチを確認する。新たにブランチを作成する​ |
| 8  | switch [branch]​  | ブランチを変更する​  |
| 9  | merge  | ブランチの変更を取り込む​  |
| 10 |  push | ローカルのcommit内容をリモートに反映する  |
| 11 | pull​ | リモートリポジトリの変更をローカルブランチに反映する​ |


## Commitメッセージにはprefixを
参照:​ [Gitのコミットメッセージの先頭につけた方が良い単語リスト(prefix集)​](https://qiita.com/muranakar/items/20a7927ffa63a5ca226a​)

コミットメッセージだけ見ても、どういった修正か分からない場合も多いので、prefixをつけるのをお勧めします​
bug修正なら「fix」、新機能なら「feat」、リネームなら「rename」といった感じです


## Pull Requestについて​
* gitの本来の機能ではなく、githubが作成したもの​
* 今ではgitリポジトリサービスを展開していると必ずついてくる​
* 本流のブランチから新たにブランチを作成して、新機能の開発やバグの修正を行い、そのブランチのマージをお願いをする事​
* 権限や知見を持った人が変更内容を確認して、マージや状況によっては却下を行う


## gitの初期設定

:::note alert
__Must__ ​
> git config --global user.name ”atakig”​
> git config --global user.email atakig@beex-inc.com​
:::

:::note info
__お好みで​__

> git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -nosession”​

```$HOME/.gitconfig​
[alias]​
st = status​
ci = commit​
dw = diff --word-diff​
dr = diff --color-words --word-diff-regex='\\w+|[^[:space:]]'​
tree = log --oneline --all --graph --decorate --color
```
:::

## CodeCommitを使う上での設定作業

CodeCommitのリポジトリ名は、AWSアカウント内でユニークとなる​
リポジトリへのUrlにはAWSアカウントIDが入っていないため、名前解決をどうしているのか不明​
スムースな作業のためにGRCを利用します​
例: https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/beex-code-commit​

> HTTPS(GRC) は、git-remote-codecommit (GRC) で使用するプロトコルです。このユーティリティは Git を拡張することで、コードを CodeCommit リポジトリに対しプッシュおよびプルするための簡単な方法を提供します。これは、フェデレーティッドアクセス、ID プロバイダー、および一時的な認証情報を使用した接続をサポートする際に推奨されるプロトコルです​


```grc.sh​
pip install git-remote-codecommit​
git remote add <name> <url>​
git remote -v​
bxcc    codecommit::ap-northeast-1://[aws-profile]@beex-code-commit (fetch)​
bxcc    codecommit::ap-northeast-1://[aws-profile]@beex-code-commit (push)
```

## CodeCommitを使ったPullRequestと承認のデモ
[内容割愛]

​

​
SeleniumとChromeDriverManagerについて（備忘録）

Seleniumでexecutable_pathが廃止されたことで
<pre>
webdriver.Chrome(ChromeDriverManager.install(), options=options)
</pre>
という今までの書き方ができなくなりました。

この書き方をすると
<pre>
TypeError: __init__() got multiple values for argument 'options'
</pre>
というエラーがでます。

対処法は
<pre>
service = Service(executable_path=ChromeDriverManager().install())
webdriver.Chrome(options=options, service=service)
</pre>
です。

<h2>
参考資料
</h2>
<a href="https://www.selenium.dev/ja/documentation/webdriver/getting_started/upgrade_to_selenium_4/#python-1">
seleniumドキュメント
</a><br>
<a href="https://github.com/SeleniumHQ/selenium/pull/12030">
selenium github コミットログ
</a><br>
<a href="https://gammasoft.jp/blog/python-selenium-webdriver-deprecation-warning-by-executable_path/">
Selenium4 WebDriver の executable_path 使用に伴う警告の回避方法
</a><br>
APサーバーが起動していなかった話

## はじめに

今回は、Ruby on RailsのアプリケーションをsystemdとPumaで起動する方法についてお話ししたいと思います。この内容は、私がうっかりやってしまったミスとその解決法を共有することを目的としています。

## なぜ起動していなかったのか？

タイトルを冒頭から回収していきますが、EC2をどこかのタイミングで再起動していました。その時にPumaを立ち上げるのを**忘れていて**(←ここ重要)、そのままなんで繋がらないのかをあれこれ考えていました。結局単純なミスなのに、もっと重大なことが起こってしまったのではないかと全然違うところを見て回っていました。

## どのように対策したか

こちらの[Qiita記事](https://qiita.com/yokku21/items/392d597f21a90e9883e0)を参考にさせて頂きました。


### 1. Pumaの自動起動用ファイルを作成する

```puma.service
[Unit]
Description=Puma AP Server
After=network.target


[Service]
Type=notify
WatchdogSec=10
User=ec2-user

WorkingDirectory=/home/ec2-user/RealWorld/

ExecStart=/home/ec2-user/.rbenv/shims/puma -C config/puma.rb

Restart=always

[Install]
WantedBy=multi-user.target

```

:::note info
ExecStartに記載するpumaとpuma.rbの場所の探し方

- pumaを探すには`sudo find / -name puma`
- puma.rbを探すには`sudo find / -name puma.rb`

:::

### 2. ファイルを移動する

上記を記載したファイルを`/etc/systemd/system/`に移動させます。

### 3. systemdに変更があったことを教えてあげる

```
sudo systemctl daemon-reload
```

### 4. 次回システム起動時に自動的に起動するように設定する

```
sudo systemctl enable puma
```

### 5. 今すぐPumaを起動させる

```
sudo systemctl start puma
```

### 6. Pumaのステータスを確認する

```
sudo systemctl status puma
```

これで **Active: active (running)** となっていたら完了です！

## まとめ

前職では普段から、システムとシステムとの間に手作業を入れないようにとか、間違った場合はどこで気がつけるようになっているのか？などと、システムを導入する時にベンダーの方へ質問していました。「**人は間違う生き物**」というのは前提に考えていたつもりでしたが、いざ自分が間違うと恥ずかしいものですね。。。
だからこそ、「気を付ける！」と気張るのではなく、「任せる」というスタンスで行きたいものです☺️
PowerShellの社内プロキシ認証を設定する


# 背景
また社内プロキシに苦しめられています。

https://qiita.com/kztktr/items/d93d49bcd01847fe0b95

Windows上でpythonのスクリプトを書こうと必要なライブラリを`pip install`しようとしたところ、案の定プロキシに阻まれました。
というわけで今回はPowerShellでネットワークに接続する際のプロキシ認証方法についてです。

# 環境
Windows10
PSVersion:5.1.19041.3031
プロキシサーバの認証には予め設定されたユーザ名とパスワードが必要。

今回は最後にpythonのライブラリを`pip install`するので、python3もインストール済みとします。

# Profileのセット前準備
忘れがちですが、まずPowerShellを管理者権限で起動します。
PowerShellのプロキシに関する設定は`Microsoft.PowerShell_profile.ps1`での記述が反映されるようになっています。
パスは`Write-Host $PROFILE`で確認できます。

```
> Write-Host $PROFILE
C:\Users\hogehoge\ドキュメント\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
```
ただし、`Write-Host`で出力されるパスは<b>設定ファイルを格納すべきフォルダを示しているだけです。</b>
ですので、この段階では実際にエクスプローラーでアクセスしてみても、ファイルは見つかりません。
PowerShell上でも`test-path`で実際にファイルが実在するか確認することができます。
下記の出力では、profileファイルは存在していないことになります。
```
> test-path $PROFILE
False
```

# PowerShellのスクリプト実行許可
というわけで、`Write-Host`で指定されているディレクトリに実際にprofileファイルを作成しますが、その前にPowerShellにスクリプトファイルの実行を許可する必要があります。
`Get-ExecutionPolicy`でポリシーを確認して、下記のように表示されたら、現在PowerShellでのスクリプト実行は禁止されている状態にあります。
```
> Get-ExecutionPolicy
Restricted
```

ちなみに、このままprofileファイルを作成しようとすると、下記のようなエラーが出ます。
```
.\hogehoge.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル DC\hogehoge.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(http://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\hogehoge.ps1
+ ~~~~~~~~~~
+ CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
```

スクリプト実行のポリシーは下記コマンドで許可できます。
「実行ポリシーを変更しますか？」と表示されますので、「［Y］はい」を選択してください。
```
Set-ExecutionPolicy RemoteSigned
```

# profileのセット
`Write-Host `で指定されているディレクトリに実際にprofileファイルを作成し、再度`test-path`でファイルが実在するかを確認します。
```
> new-itme -path $profile -itmetype file -force
> test-path $PROFILE
True
```
# Profileにプロキシ設定を記述
作成したprofileファイルをVScodeなりのエディタで開き、プロキシ設定に関する記述を書いていきます。
```
# profile読み込み確認
Get-Host

# 個別の認証情報
$proxyUser = "<USERNAME>"
$proxyPassword = "<PASSWORD>"
$proxyhost = "<HOSTNAME>:<PORTNUMBER>"

# 環境変数
$proxyAddressWithAuthenticattion = "http://$($proxyUser):$($proxy$password)@$($proxyhost)"
$env:http_proxy = $proxyAddressWithAuthenticattion
$env:https_proxy = $proxyAddressWithAuthenticattion
$env:ftp_proxy = $proxyAddressWithAuthenticattion

# クレデンシャル設定
$passwordSecure = ConvertTo-SecureString $proxyPassword -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential $proxyUser, $passwordSecure
$proxy = New-Object System.Net.WebProxy "http://$($proxyhost)/"
$proxy.Credentials = $creds
[System.Net.WebRequest]::DefaultWebProxy = $proxy
```
`# 個別の認証情報`のプロキシ認証に関係する情報を記載していきます。
作成できましたら、PowerShellを再起動します。管理者権限もお忘れなく。
ここまでで、プロキシ認証作業は完了です。

# pip install でプロキシ認証されているか確認
当初の目的であるpythonのライブラリをインストールして、プロキシ認証ができているかを確認します。
```
> pip install openpyxl
```
これでインストールができましたら、PowerShellでプロキシ認証できていることを確認できたことになります。

# 参照
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.3

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_scripts?view=powershell-7.3
IBM Cloud上でのVMware vSphereオファリングの導入

# はじめに
IBM Cloud上にVMware vCenter環境を構築します。IBM Cloudでは、以下の４つのVMwareオファリングが利用可能です。
1. VMware as a Service
1. VMware Shared
1. VMware vCenter Server
1. VMware vSphere

今回は、VMware vSphereを選択します。
各オファリングの特徴の詳細および比較については、https://cloud.ibm.com/vmware/compare_offerings をご覧ください。

# VMware vCenter環境構築の準備
1. VMware vSphereオファリングのオーダー
IBM Cloudのカタログより`vmware`で検索し、`VMware Solutions`を選択します。
オファリングの選択肢に`VMware vSphere`がありますので、そのパネルにマウスカーソルを合わせて、`作成 +`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3063877/a71ac58e-fa3d-e38f-eea8-a47864360adb.png)
VMware vSphereオファリングを作成すると、ESXiが導入されたベアメタル・サーバーが作成されます。ESXi上にvCenter Serverをインストールするのは、ユーザーの作業になりますので、ご注意ください。

2. VMware vCenter Server Applianceインストーラーの入手
`1. VMware vSphereオファリングのオーダー`時にライセンス交付のところで`VMware vCenter Server`にチェックを入れることでライセンスキーを入手できますが、VMware vCenter Server Applianceのインストーラーはユーザーが入手する必要があります。IBM Cloudのドキュメントでは、`VMwareポータルからダウンロードします`という記述がありますが、VMwareポータルにアカウントを作成してから評価期間を過ぎていた場合、ダウンロードできないことがあります。この場合は、IBM Cloudのポータルから`Case`を起票することで、サポートの方がユーザーに代わってインストーラーを入手してくれます。インストーラーの共有方法ですが、私の場合は`Box`でした。

3. ジャンプ・サーバーの準備
IBM Cloudのクライアント・アクセスVPNは管理用のため速度が制限されています。vCenter Server Applianceのインストーラーは9GB近くありますので、VPN接続したリモートPCから導入作業を行うのは現実的ではありません。そのため、作成されたベアメタルと同じサブネットにジャンプ・サーバーを作成し、その上でインストーラーを実行するのが推奨されています。
ここではジャンプ・サーバーとして、Windows Serverを使用します。作成する際のプロファイルは最小構成で構いません。Windows Serverが作成されましたら、VPNを接続し、Remote DesktopアプリでWindows Serverにアクセスします。
次に、Windows Serverでブラウザーを開き、`2. VMware vCenter Server Applianceインストーラーの入手`で共有されたBoxリンクにアクセスして、インストーラーをWindows Serverにダウンロードします。VMwareポータルからダウンロードされる場合も、ローカルPC経由でアップロードするのではなく、Windows Serverから直接ダウンロードされることをお勧めします。

# 終わりに
今回は、VMware vSphereオファリングの導入からジャンプ・サーバーまでの内容となりました。次回の記事では、ジャンプ・サーバーにダウンロードしたvCenter Server Applianceをインストールします。

https://qiita.com/cxl2022my/items/8eef53123f0f6a8f514a
【Cisco_設定】Catalyst9000シリーズ(上位機種)の冗長構成でStandby機のコンソールアクセスを有効にする方法

C9000シリーズ(主に9500以上の上位機種)で冗長構成(Virtual Stackwise)を構築した場合、Standby機でのコンソールアクセスはデフォルトでは無効になっている。有効にする場合は、Active機から以下の設定を実施する。

C9800#conf t
C9800(config)#redundancy
C9800(config-red)#main-cpu
C9800(config-r-mc)#standby console enable
C9800(config-r-mc)#end
はじめて読む486　1 プロローグ

## 1.1 486のパワー

- オペレーションシステム
    - MS-DOS, Windowsのように、CPUや他の機器と一般ソフトウェアとを結びつける特別なソフトウェア
    - CPUの能力（機能、量）を引き出す

## 1.2 オペレーティングシステムサポート機能のパワー

- 486の動作モード
    - リアルモード
        - MS-DOS用アプリケーション
    - プロテクトモード
        - Windows用アプリケーション
    - 仮想8086モード
        - MS-DOS用アプリケーション
        - 拡張機能を利用した新しいOS管理下で使える
        

| リアルモード | 物理メモリ | セグメントサイズ | セグメント機能 | 保護機能 | タスク機能 | 32ビットサポート | 仮想8086モード |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 8086/186/V30 | 1M | 64K | ○ |  |  | ○ |  |
| 286 | 1M | 64K | ○ |  |  | ○ |  |
| 386 | 1M | 64K | ○ |  |  | ○ |  |
| 486 | 1M | 64K | ○ |  |  | ○ |  |

| プロテクトモード | 物理メモリ | セグメントサイズ | セグメント機能 | 保護機能 | タスク機能 | 32ビットサポート | 仮想8086モード |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 286 | 16M | 64K | ○ | ○ | ○ |  |  |
| 386 | 4G | 4G | ○ | ○ | ○ | ○ | ○ |
| 486 | 4G | 4G | ○ | ○ | ○ | ○ | ○ |

## 1.3 32ビットパワーの体験

- 8086の壁
    - 64Kの壁
        - セグメントアーキテクチャの制限
        - 連続してアクセスできる領域が64K
        - メモリアドレスの指定に16ビット（0~65535）を使うため
    - 640Kの壁
        - アドレスを20ビットで表現しているため、アドレス空間を1Mバイトしかとれない
            - メモリ自体は存在しても使うことが出来ない
        - そのうち先頭の640Kバイトまでのアドレスはメモリ、それ以上を画面表示用のハードウェアやBIOS用のROMを搭載するために使用している
国際会議PAKDD2023に聴講参加してきました

# はじめに
先日、国際会議であるPAKDDに聴講参加してきましたので、その様子をお伝えします。
PAKDD2023ホームページ (https://pakdd2023.org/)

# PAKDD とは
PAKDDは「The Pacific-Asia Conference on Knowledge Discovery and Data Mining」の略称で、知識発見とデータマイニング分野を扱う国際会議の 1 つです。
第27回目が2023/5/25〜5/28に大阪で開催されました。せっかくの日本での開催ということで、現地参加してきました。


# プログラム
初日5/25に、チュートリアルとワークショップがオンラインのみで実施されました。
5/26〜5/28には、合計で143の論文発表（現地・オンラインのハイブリッド）があり、論文のカテゴリとしては、ディープラーニング、テキスト、グラフ・ネットワーク、推薦システム、異常検知・外れ値検知、時系列データ・ストリーミングデータ、分類、医療データ・生物学データ、時空間データ、情報の取得・検索、解釈性・説明性などがありました。


# Best Paper Award
各種Awardが PAKDD2023ホームページ (https://pakdd2023.org/awards/) に掲載されています。
Best Paper Award は、下記のバックドア攻撃の検出に関する論文が受賞しました。

> - Defending Against Backdoor Attacks by Layer-wise Feature Analysis
>   　Najeeb Jebreel (Universitat Rovira i Virgili)
>   　Josep Domingo-Ferrer (Universitat Rovira i Virgili)
>   　Yiming Li (Tsinghua University)

バックドア攻撃とは、モデルを学習する際に攻撃者が細工したデータを学習データに入れることによって、特定のトリガーを含むデータに対して誤分類させる攻撃のことです。
上記の論文では、各データに対して層別に特徴を分析することで、正常なデータと細工されたデータを見分けることができる手法が提案されました。

# 各発表について
今回は同僚と2人で参加しました。別のQiita記事で、各発表について同僚がまとめていますので、ぜひご覧ください。

PAKDD2023報告 (https://qiita.com/motonobu_ut/items/365abd8f4ec9fb9af7a4)

# Banquet
5/27にはBanquetがありました。世界中の研究者の方々とお話しでき、非常に刺激を受けました。終盤には歌舞伎の上演もあり、多くの方が楽しんでいました。

![歌舞伎.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470712/f7bd5b5f-1de3-b375-d017-058bc5840f57.jpeg)


# PAKDDオリジナルキャラクター
PAKDDオリジナルキャラクターのお菓子やトートバッグが配布されました。良く見るとPAKDDの文字が見えます！かわいいです。

![PAKDDトートバッグ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470712/5eb3d4d2-b0ee-b274-b821-7b4f72910830.jpeg)
AWS DNSリゾルバーの概要整理

# AWS DNSリゾルバーの概要について

VPCを立てるとDNS Route 53 ResolverというものがDefaultで付与される（*.*.*.*.2など）

それに付随して、Resolver インバウンドエンドポイント、Resolver アウトバウンドエンドポイント
というものを付与可能

### インバウンドエンドポイントを立てるメリット
　GCPやオンプレなどの外部ネットから、インバウンドエンドポイントへアクセスできれば、名前解決して、Route53で設定された名前解決を行うことができる

#### 経路
外部　→ インバウンドエンドポイント

### アウトバウンドエンドポイントを立てるメリット：
　アウトバウンドエンドポイントを立てなくても、外部ネットのDNSサーバーのIPを直接指定すれば、nslookupは可能
　ただ、アウトバウンドエンドポイントを立てれば、Resolver自体をDNSサーバーとして指定すれば名前解決ができるようになる。
　（ここで立てるというのは、例えばエンドポイントをコンソールなどで作成し、hogehoge-outer.localの場合は、外部DNSサーバーの10.1.0.3に接続するという設定を行うなど）

#### 経路
内部 → リゾルバー → 外部DNSサーバー
GradleでBOMを指定する (MavenのDependency Management相当)

# 背景
今やっているPRJで同一groupIdの複数のモジュールを取り込む機会があって、ちまちまバージョン指定するのが嫌だったのでやり方を調べた。

# 結論
BOMが提供されている場合、`implementation platform`をつかう

```gradle:build.gradle
dependencies {
    // gcp
    implementation platform('com.google.cloud:spring-cloud-gcp-dependencies:4.4.0')
    implementation 'com.google.cloud:spring-cloud-gcp-starter-storage'
    implementation 'com.google.cloud:spring-cloud-gcp-starter-bigquery'
    implementation 'com.google.cloud:spring-cloud-gcp-starter-logging'
}
```
ちなみにGradle5.2以降でしかこの書き方はできないっぽい。新しいバージョンを使うようにしましょう

# その他

## Spring Boot
Spring Bootは上記を使わなくてもpluginを読み込むだけでバージョンが指定できる。楽チン
```gradle:build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.0' // こいつでSpring Bootのバージョン指定
    id 'io.spring.dependency-management' version '1.1.0' // これも必須。入れないと依存解決ができない
}
```

## Dependency Management Plugin
上記で読み込んだ`io.spring.dependency-management`を使うと、`implementation platform`を使わなくても以下のようにも指定できる
```gradle:build.gradle
dependencyManagement {
    imports {
        mavenBom 'com.google.cloud:spring-cloud-gcp-dependencies:4.4.0'
    }
}
```

BOMが指定できない場合でも、以下のような書き方で共通のバージョンを指定することもできる
```gradle:build.gradle
dependencyManagement {
    dependencies {
        dependencySet(group:'com.google.cloud', version: '4.4.0') {
            entry 'spring-cloud-gcp-starter-storage'
            entry 'spring-cloud-gcp-starter-bigquery'
            entry 'spring-cloud-gcp-starter-logging'
        }
    }
}
```

# 参考
* https://docs.gradle.org/current/userguide/platforms.html#sub:bom_import
* https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/