OmniAICreator/Qiita-1.07M huggingface dataset:
Googleが開発途中の言語 Runeを触ってみた

この記事は DeNA 23 新卒 Advent Calendar 2022 の7日目の記事です。

Googleが開発中の言語 Runeを簡単に触ってみました。
執筆時点(2022年12月)では、まだ日本語のドキュメントや記事が見つからなかったため、簡単な使い方と文法についてまとめます！

https://github.com/google/rune

# Runeとは

RuneはPythonにインスパイアされた静的型付け言語で、メモリ安全性、秘密の定時間処理など、多くのセキュリティ機能を備えています。
ファイル拡張子は`rn`で、主にCやC++のライブラリとうまく相互作用するように設計されています。
Structure-of-Array (SoA) メモリ管理により、メモリ集約的なアプリケーションにおいては、C++よりも高速であることを目指しているそうです。

GitHubリポジトリを見る限り、最初のコミットは2021年11月で、まだ開発されたばかりの言語ということがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629156/05a82165-060f-7cb9-ee30-781e7c3b6cc7.png)

# 文法

実装されていない箇所やドキュメントにない文法などもあるので簡単にまとめます。

## 型
- 文字列
- 数値
- bool型
- 動的配列
- 静的配列(タプル)
- 関数ポインタ

数値はデフォルトでu64として扱われるようになっています。

## 変数

Pythonのように変数を定義できます。

```bash
str = "Hello, World!"

int = 1234

array = ["1", "2", "3", "4"]

boolean = true
```

## 関数

関数は以下のように宣言でき、タイプヒンティングを行うこともできます。

```rune
// タイプヒンティングなし
func Add(a, b) {
  return a + b
}

// タイプヒンティングあり
func Add(a: u8, b: u8) {
  return a + b
}
```

## クラス

クラスは命名のみPythonライクな書き方となっており、キャメルケースでの実装になっています。
クラス定義の最上部列がPythonでいう`__init__`メソッドになっています。

```rune
class Person(self, name) {
	self.name = name

	func helloWorld(self) {
		println "Hello, world, from ", self.name, "."
	}
}

relation DoublyLinked Human:"Mother" Human:"Mothered" cascade
relation DoublyLinked Human:"Father" Human:"Fathered" cascade
```

Runeでは、クラスの関係性(Relationships)を`relation`で定義でき、クラス同士で紐づくデータを高速、かつ、簡単に表現できます。
以下は使用できるRelationshipsです。

```rune
ArrayList
DoublyLinked
Hashed
HeapqList
LinkedList
OneToOne
```

## コメント

コメントは、C言語ライクな書き方をします。

```rune
// This is a single-line comment.
/*
  This is a block comment.
  Note that /* embedded comments */ do not end the comment block.
*/
```

## 演算子

```rune
!    !=   &=  :     <=  >>=   []  |=
!+   %    ()  <     <>  >>>=  ^   ||
!+=  %=    +  <<    =   @     ^=  ||=
!-   &    +=  <<<   ==  @=    /    ~
!-=  &&    ,  <<<=  >   @@    /=
!<   &&=   -- <<=   >=  @@=   |
```

## 代入演算子

```rune
!+=  !=  &&=  +=  <<<=  <=  ==  >>=   @=   ^=  ||=
!-=  %=  &=   -=  <<=   =   >=  >>>=  @@=  |=
```

# 実行方法
ここでは、`Hello, World!`を表示させてみたいと思います。

```bash
$ echo 'println "Hello, World!"' > hello.rn
$ rune -g hello.rn
$ ./hello
Hello, World!
```

`rune -g`コマンドでファイルを指定し、バイナリを生成すると実行できるようです。

ちなみに、コンパイルエラーは`rune -g`コマンド実行時にエラー元を表示してくれるようになっています。
(以下は、文字列の1と数値(u64)の1を演算できないというエラーです)

```rune
$ rune -g hello.rn
Error: Non-equal types passed to binary operator
File hello.rn, line 24: println "1" + 1
Stack trace:
Exiting due to error...
```

# 実行環境について

Runeは執筆時点だとmacOSやWindowsのサポートはしてないようなので、私はUbuntuサーバーを用意し実行環境を構築しました。

[mattnさん](https://twitter.com/mattn_jp)によるとWindowsであれば、中身をいじると動くようです。

https://twitter.com/mattn_jp/status/1597553846683070465?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1597553846683070465%7Ctwgr%5Ea0c36f2dd6f49fe11cfb9990df91497195166345%7Ctwcon%5Es1_c10&ref_url=https%3A%2F%2Fqiita.com%2Fdrafts%2Fd7cf1b8eee17502c2121%2Fedit

# まとめ

一通り触ってみましたが、特段Python味は感じなかったです。
(私がPython歴が長くないのもあるかもしれませんが、、)

まだ開発され始めたばかりのため、色々整ってはいないなど、まだまだこれからな部分があると感じました。
Rustなどが流行り、セキュリティやメモリ安全が話題になっている中で、今後Runeが言語としてどのようなポジションになっていくのかが楽しみです!
virt-managerでリモートホストとSSH接続する際に鍵ファイルを使う方法

Linux上の仮想マシンをGUIで管理するのに便利なvirt-managerですが、リモートホストとSSH接続で鍵認証を使う際にGUIでは設定ができません。
そんな時はコマンドラインから鍵ファイルを指定すると、うまく接続＆登録できるようです。

例）
アカウント名：ubuntu
リモートホストのIP：192.168.0.1
鍵ファイル：`/home/ubuntu/.ssh/id_ed25519`
```bash
$ virt-manager -c 'qemu+ssh://ubuntu@192.168.0.1/system?keyfile=/home/ubuntu/.ssh/id_ed25519'
```
Service Catalog新機能「注文ガイドの順序付け」

# はじめに
みなさんこんにちは、三井情報株式会社です。

今回はSan diegoでのService Catalog新機能「注文ガイドの順序付け」についてご紹介致します。
※言語設定を英語にして実装することを推奨します。

# 注文ガイドの順序付け
①	プラグインのインストール（アクティブ化）
Order Guide Sequential Fulfillment (com.glideapp.servicecatalog.order_guide_sequencing) プラグインをインストールすることで利用可能です。既にインストール済の場合は関連リンク（Related Links）の「アクティブ化（Activate）」を押下し、ステータスをアクティブにします。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/6483a1bf-aa1b-ad3e-5b9e-1a58d08919a0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/67592acf-3344-4e79-48ec-e8f7fb74f6bb.png)

 

②	注文ガイド（Order Guide）の作成
フィルタナビゲータからカタログ定義（Catalog Definitioins）＞注文ガイド（Order Guide）を検索し、新規（New）を押下して注文ガイド（Order Guide）レコードを新規作成します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/db419282-55b0-e588-c50e-2c953c759d6f.png)


名称（Name）、カタログ（Catalogs）、カテゴリ（Category）を設定します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/8d665b42-4773-2d17-9ae8-24410c562706.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/e1c8aff7-225f-7761-f401-5bcde1c35c77.png)

 

関連リンク（Related Links）からルールベース（Rule base）を作成します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/0876aa0e-7180-ecb8-6182-4651512fc050.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/f5a46bde-0337-4983-70a2-1073f5b71780.png)

 

シーケンスを生成（Generate sequence）を押下するとProcess Automation Designerが開きます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/b0c77647-4a90-6b5d-dc7e-36a8f7587188.png)


Process Automation Designerにて新規にアクティビティを作成し保存します。
※日本語だとうまく動作しない可能性があります。（日本語ラベルの設定は問題なし）
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/9655b827-f5f6-999f-b6ac-33f3735da48c.png)


右上のTestを押下することでテストできます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/18f99df7-1991-ebd3-5453-3388e1c27d58.png)


Viewを押下することでテスト結果が確認できます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/eb551d70-b9cd-5386-10ff-5f31e4c09259.png)


Try Itから実際にカタログの使用感を確認できます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/c57356e7-423d-3364-31eb-3574476041a1.png)


2つのアイテムを選択しCheck outを押下するとそれぞれについて注文できていることが確認できます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/8ffaefcf-e777-f758-ef4f-120b262646f2.png)


Service Portalでの表示は以下のようになります。
Choose OptionsにてDevelopment LaptopとStandard Laptopそれぞれの項目について開いて選択できます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/227f2c74-3b10-3313-970c-60f018b3d884.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/619eb179-dcaa-41a1-12f5-8abd18fef43c.png)

 


# おわりに
今回はSan diegoでのService Catalog新機能「注文ガイドの順序付け」についてご紹介させていただきました。
最後まで読んでいただき、ありがとうございました。
【Swift】初心者のランダム通話アプリ開発奮闘記 #5

# 今日の積み上げ
画像ファイルをプレビューに表示
※SpyFamily面白いですよね

iPhoneで撮影した写真をAssets.xcassetsにドラック&ドロップ
→チュートリアル通りに```.clipShape(Circle())```属性を付与したところ、Xcodeがクラッシュ、、
→→安定のGoogle先生に力をお借りして、アーニャを召喚しました（画像参照）

![2022:12:02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/997222/9af6eb39-fc43-eb7f-5f58-975eb4cc33bf.png)

週明け月曜日からの仕事が憂鬱すぎる、、
なぜ、iOSのアプリを自作するモチベはあるのに自分の会社にコミットできないのか。おそらくフルリモートで会社への帰属意識がないからであろう。月曜日の俺頑張れ。
Cobalt Strike悪性コードの検知方法：攻撃を受けたボットネットサーバー探索

ペネトレーションテストツールとして使われるコバルト・ストライク（Cobalt Strike）が悪意的な攻撃者によってランサムウェアの攻撃あるいは内部システムへの侵入を目的として悪用される事例がしばしば発生します。主にボットネットを活用してコバルトストライクを配布し、ランサムウェアとPC感染攻撃を犯す経路で行われます。今度の投稿では、合法的かつ悪意的な理由で Cobalt Strike悪性コード に感染したサーバーをCriminal IP検索エンジンで検知する方法を扱います。

# Cobalt Strike悪性コード とは
Cobalt Strikeは有料のペネトレーションテストツールで、多くのRed Teamが攻撃シミュレーションのソフトウェアとして使います。
![Cobalt Strike_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/b12a59e6-4f3b-ef1a-c4aa-0d6df1c18bae.png)
しかし、全てが合法的に Cobalt Strike を活用するわけではありません。サイバー攻撃者はダークウェブで共有される海賊版の Cobalt Strike を実際の攻撃行為に悪用します。なので、 Cobalt Strike はペネトレーションテストツールでありながら同時に深刻な悪性コードに分類されることもあります。

そのように、 Cobalt Strike は一般的な悪性コードとは違って合法的に配布される場合もあるので、攻撃の検知はさらに難しいです。最近は Google Cloud Threat IntelligenceチームがCobalt Strike 攻撃を検知するオープンソースのYARAルールを公開したりもしました。

# Cobalt Strike悪性コードに感染したBotNet サーバーを検知
オープンソースルールに従って Cobalt Strike 攻撃の検知を行えますが、より簡単に Cobalt Strike に感染したサーバーを見つける方法があります。Security OSINT 検索エンジンであるCriminal IPのIT資産検索でタグ・フィルターを活用することです。
- https://www.criminalip.io/ja/asset/search?query=tag:%20Cobalt%20Strike
- Search Query : “tag: Cobalt Strike”
![Cobalt Strike_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/573a4ff4-d07a-b199-2b7c-50bb7679340d.png)

検索結果、外部に繋がったサーバーの中で Cobalt Strike に感染したサーバーは総計102個に検知されました。この102個のサーバーは既に Cobalt Strike に感染したボットネットサーバーとみなせます。

もちろん、合法的に使用された Cobalt Strike が含まれた可能性もあるため、全部攻撃だと判断することはできませんが、検索されたサーバーは内部システムへのアクセスを許可しているか、ランサムウェアに感染した可能性の高いサーバーだと言えます。

# Cobalt Strike感染 サーバー国家の統計、1位は中国
Cobalt Strike に感染しているボットネットサーバーが一番多い国は中国で、全て54件です。- 
- https://www.criminalip.io/ja/intelligence/element-analysis/search?query=tag%3A+Cobalt+Strike
![Cobalt Strike_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/17046a63-c743-0ab6-1507-63cd3a539ced.png)

また、次のように感染したボットネットサーバーのポートの統計を見ると、大部分80ポート、8080ポートに検知されました。
* https://www.criminalip.io/ja/intelligence/element-analysis/search?query=tag%3A+Cobalt+Strike
![Cobalt Strike_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/7e434579-6201-0882-e1eb-7e5a07745d3c.png)

# Cobalt Strike Beaconに感染したボットネットサーバーのIP Intelligence
Cobalt StrikeによりBeacon悪性コードが設置されているボットネットのIPアドレスをCriminal IPのIT資産検索で検索し、IP Intelligenceを追加で分析できます。
![Cobalt Strike_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/e60bfb3e-96b2-7341-5868-b06fa31e89ca.png)
該当IPアドレスはInbound脅威スコアが99％のCriticalに診断されました。既に攻撃に使われたか、使われかねないからです。
Cobalt Strike タグで分類されたTCP 80ポートのバナー情報をみると、 Cobalt Strike に対する情報を確認できます。
![Cobalt Strike_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003594/1cd29241-6874-3412-620d-d3558972b0f4.png)
このように、Security OSINT検索エンジンのCriminal IPを活用して簡単に Cobalt Strike悪性コードに感染したサーバーを見つけることができます。検索エンジンまたは、APIで自動検知することができ、特定サーバーの感染有無をチェックするか、インバウンドIPのブロックBlacklistに感染したサーバーを追加するために使えます。
【livewire2.0】プロパティにEloquentCollectionを使う際の注意点

## 概要

livewireコンポーネント内のプロパティで使える型に、EloquenCollectionがあります。
> 通常のSupportCollectionは使えません

EloquentCollectionの便利な所は
内包しているEloquentモデルオブジェクトをlivewireが勝手に配列にしてしまわない所です。

基本的にモデルオブジェクトを内包した配列を生成した場合、モデルオブジェクトが全て配列に変換されてしまいます。
```php
$this->hoge[] = User::find(1);
```
上記のように記述した場合、レンダリング時にUserモデルオブジェクトがただの配列になります。
EloquentCollectionなら特定のモデルオブジェクトを取り出した際に、モデルが持つ振る舞いを使用する事ができます。

ですが使用する際に注意点があります

## 永続化されてないモデルオブジェクトをpushするとエラーが発生する

以下のようなlivewireコンポーネントがあるとします

### php側
```php:
<?php

namespace App\Http\Livewire;

use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;

class Sample1202 extends Component
{
    public Collection $users;

    public function mount()
    {
        $this->users = User::all();
    }

    public function render()
    {
        return view('livewire.sample1202')
            ->extends('adminlte::page')
            ->section('content');
    }

    public function addUser()
    {
        $this->users->push(User::make([
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'password' => 'password'
        ]));
    }
}

```

### Blade側
```html
<div>
    @foreach($users as $user)
        <p>id: {{ $user->id }}</p>
        <p>名前:{{ $user->name }}</p>
    @endforeach
    <button wire:click="addUser">追加</button>
</div>
```

### DB

![スクリーンショット 2022-12-02 16.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/a6e186a7-059f-fbc3-2a1e-bc9c9704fc39.png)

## 永続化されてないモデルオブジェクトを追加する

### 画面

![スクリーンショット 2022-12-02 16.49.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/cfe825af-85ec-323c-4d80-fffc0a0ec478.png)

書いたコード通りだと、追加ボタンを押すと``John Doe``さんが追加されます。

追加ボタンをクリックします。

![スクリーンショット 2022-12-02 16.50.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/5a14d642-e0d2-32f6-dafb-9e82d07070db.png)

はい、追加されました。問題なさそうですね。ではもう一度クリックします。

![スクリーンショット 2022-12-02 16.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/45dfa900-c991-6afa-22b4-be86247643c1.png)

なにやら見慣れないエラーが出ましたね。

> Queueing collections with multiple model connections is not supported.
> 複数のモデル接続を持つコレクションのキューイングはサポートされていません。


## 対処法

Modelオブジェクト生成時に接続先を教えてあげます。

```php: Models/User.php
public function getConnectionName()
{
    return $this->connection ?? config('database.default');
}
```

## なぜこんなエラーが起きるのか？

livewire内でEloquentCollectionを使うと、
レンダリングする度にEloquentCollection内のモデルオブジェクトを全て最新の状態にする処理が走ります。

実際に見てみましょう。


![スクリーンショット 2022-12-02 16.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/f4a5d6f9-ce65-deb7-d441-ef6e2ba7fc07.png)

まずこの状態から、DBを直接弄って一番上の人の名前を書き換えます

![スクリーンショット 2022-12-02 17.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/306e26de-8125-642e-e495-9fd38a26df2f.png)

この状態で追加ボタンを押してみます。

![スクリーンショット 2022-12-02 17.00.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/434bfe9a-76e0-e9ff-31b9-caf5d95240f6.png)

はい、livewireコンポーネント内で再取得する処理を記述していないのに更新されました。

これを行おうとした際に発生するエラーという訳です。
実際にどういう処理が行われているのかはまた今度コードの海に潜ってみようと思います。

今回分かったのは大枠の原因と対処法です。
NFT のロイヤリティ還元はそもそも強制手段はなかった

> NFTの凄いところは、販売時点だけでなく、転売時（二次流通時）にも永遠にクリエイターにロイヤリティーが入る仕組みが実装できる

というお話はどこかで聞いたことがあると思いますが、結論からしますと、いろいろ制限されている条件の前提でしか成り立たないことでした。

NFT のスマートコントラクトを実装したことがあればわかると思いますが、ERC 721 / ERC 1155 のスマートコントラクトの標準的な実装に NFT を転送する関数がありますが、そこにロイヤリティ還元するロジックを入れるのは、現実的ではないというか、そもそも転送するタイミングでは取引の価格・ロイヤリティの情報を知る手段がないため実装できません。

なので、結局ロイヤリティの支払いは、opensea のような、取引が発生するマーケットプレイス側の実装次第になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4777/b820a834-df51-526c-8c0f-0763d5e9678a.png)

参照元：https://www.caa.go.jp/policies/policy/consumer_policy/caution/internet/assets/internet_committee_220715_08.pdf

## ERC 2981 について
NFT のロイヤリティに関する規格 [ERC 2981](https://eips.ethereum.org/EIPS/eip-2981) がありますが、この規格の内容は強制徴収ではなく、ただ単に いくら還元すべきかの情報を提供する手段でした。

> Simple Summary
 A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal support for royalty payments across all NFT marketplaces and ecosystem participants.

また、規格の設計上は、考えられるロイヤリティの受取人への支払い方法を完全に対応するのが不可能であるため、シンプルにロイヤリティの受け取るアドレスは、１つしか設定できません。

## opensea の動向
もともとは ERC 2981 サポートしておらず、 opensea サービス上の独自の設定値（コントラクトの所有者がその値を設定できる）に従って、ロイヤリティを還元するようになっていました。

2022 年 11 月の最新方針が発表されました。

- ロイヤリティを強制還元するオンチェーンツールを公開
    - https://github.com/ProjectOpenSea/operator-filter-registry
    - 上記コードには他のロイヤリティをスキップするマーケットプレイスへの移転を禁止する処理がある
    - 既存の発行済の NFT はコードを入れなくてもロイヤリティを還元し続ける
- これから新しくデプロイされるコントラクトは、上記コードを導入しないと ロイヤリティを還元しない

## まとめ
NFT が転売時にも永遠にクリエイターにロイヤリティ還元されるとの神話がありましたが、現実は意外に厳しいです
負荷テストの指標について

負荷テストは開発したシステムが**どの程度の負荷に耐えられるか**を指標を決めて確認するテストです。

一般的には同時接続ユーザー数を性能指標に置くことが多いですが、指標は他にもあります。主に列挙すると↓です。

 - **同時接続ユーザー数**
 - **同時間のユーザーシナリオ実行本数**
 - **時間あたりのページ表示数・ページ処理数**
 - **時間あたりのユーザーのアクション数(ヒット数)**
 - **サーバーの平均応答時間**
 - **サーバーのCPU使用率**

ここで大事な考え方は何が一番ボトルネックになるのかを考えて指標を決定することにあります。
例えば1万人がWebサイトに同時接続をできたとしてもサイトのページ表示が重ければ十分な負荷テストを実施しているとは言い切れないです、Webサイトの特徴を考えて適切な性能指標を選択することで良い負荷テストが実施できるようになります。

また、よくある障害と再発防止パターンの1つとして
**「負荷テストを実施したが想定していた指標値よりオーバーしたためシステムダウンした」⇨「今後は性能指標を○倍して負荷テストを実施する」** があります。(前職でも1年に一度は体験しました)

負荷テストの指標を過去の負荷テストにしてしまうとこのような事象が起こりやすいので事業が拡大するタイミング・システム基盤が入れ替わるタイミング等で負荷指標の見直しを実施すると大部分をカバーしやすいです。
Headless CMSを基本からまとめてみた【超入門】

## Headless CMSとは？
ヘッドレスCMS（Headless CMS）とは、Webページの「ヘッド」、つまり「フロントエンド」がないCMSのこと。

※ CMS（コンテンツ・マネジメント・システム）とは、ブログやWebサイトなどで活用されているコンテンツを管理するための仕組み。代表的なものとしてWordPressやMovable Typeが挙げられ、主にWebサイト制作に使用される。WordPressなどの通常CMSは、コンテンツデータ（テキスト、画像、動画など）を表示させるビュワーと、これらのコンテンツデータを管理するシステムが統合されて成り立つ。


##### 従来のCMSとヘッドレスCMSの違い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/a7886cff-f7c1-03ab-d44e-d85e07d3c843.png)


## 参考サイト
[Headless（ヘッドレス） CMSとは？ 代表的な１０のCMS比較！](https://wk-partners.co.jp/homepage/blog/hpseisaku/htmlcss/headless-cms/)
[今話題の「ヘッドレスCMS」とは？ Jamstack、マルチデバイスにも対応したCMSの新潮流](https://codezine.jp/article/detail/15054)
[Web制作の新しい潮流「ヘッドレスCMS」とは？主要ツールの比較も併せてご紹介](https://bluemonkey.jp/media/column/Headless_CMS)
Azure Administrator(AZ-104)：Azure管理者向けの前提条件「リソースの定義(Bicep)」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「リソースの定義(Bicep)」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure 管理者向けの前提条件](https://learn.microsoft.com/ja-jp/training/paths/az-104-administrator-prerequisites/)
◇まとめとリソース
[Azure Resource Manager テンプレートを使用してリソースを構成する](https://learn.microsoft.com/ja-jp/training/modules/configure-resources-arm-templates/8-summary-resources)
◇対応するモジュール
[リソースの定義](https://learn.microsoft.com/ja-jp/training/modules/build-first-bicep-template/3-define-resources)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure管理者向けの前提条件「Bicepテンプレート」](https://qiita.com/fsd-jume/items/ed10dcf31ae66b89270c)

## リソースの定義(Bicep)
### リソース定義のコード例
・「toylaunchstorage」という名前のストレージアカウントを作成する場合
```:リソース
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = {
  name: 'toylaunchstorage'
  location: 'westus3'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}
```
**※コードの意味**
**・resource `シンボリック名` `リソースの種類@APIバージョン`**
リソースを定義していることをBicepに指示
　-シンボリック名(storageAccount)
　　Bicep内で参照の為に使用される任意の名前(Azure上では表示されない)
　-リソースの種類(Microsoft.Storage/storageAccounts)
　　作成するリソースの種類を指定
　-APIバージョン(2021-08-01)
　　Bicepがリソースを作成するときに使用するAPIのバージョンを指定(今回はAzure Storage APIを使用)
**・name**
作成されるリソースの名前
**・location**
作成されるリソースのリージョン
**・sku name**
作成されるストレージアカウントのSKUを指定
**・kind**
作成されるストレージアカウントの種類を指定
**・properties accessTier**
作成されるストレージアカウントのアクセスレベルを指定

### リソースの依存関係
**リソースのデプロイ順序が依存関係により決まる**
⇒ARMが依存関係を評価し、依存関係があればその順番に、なければ並行してデプロイされる

**◆依存関係の例**
・あるリソース宣言が同じデプロイ内の別のリソースを参照している場合
・リソース宣言の中でリソースをさらに宣言している入れ子構造になっている場合
・リソースに親プロパティが含まれている場合(例：[子]ファイルサービス → [親]ストレージアカウント)

**◆依存関係のコード例**
・App Serviceアプリを作成したい → 最初にApp Serviceプランを作成する必要がある(依存関係)
```:リソース
resource appServicePlan 'Microsoft.Web/serverFarms@2021-03-01' = {
  name: 'toy-product-launch-plan'
  location: 'westus3'
  sku: {
    name: 'F1'
  }
}

resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = {
  name: 'toy-product-launch-1'
  location: 'westus3'
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}
```
**※コードの意味**
**・properties serverFarmId**
プランのリソースIDで依存関係を認識
**・appServicePlan.id**
プランのリソースIDを取得
　-appServicePlan
　　前に定義したアプリのシンボリック名
　-.id
　　一意の識別子(ID)を返すプロパティ
**・httpsOnly**
アプリへのアクセスをHTTPSのみに制限

## 次の学習内容
**◆パラメーターと変数(Bicep)**

https://qiita.com/fsd-jume/items/52c2d957028072ed547d

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
WSL(Ubuntu)でのJavaバージョンの切り替え方法

開発で結構頻繁にJavaのバージョンを切り替えるのに、
いつも忘れて毎回検索してしまうのでまとめておきます。

# alternativesを使う方法

前提として以下のような感じでaptで複数のJDKがインストールされているとします。
※普通同時に複数バージョンをインストールしたりはしないでしょうが・・・

```bash
$ sudo apt install openjdk-11-jdk openjdk-17-jdk
```

### 切り替え

切り替える場合は以下のコマンドを実行します。

```bash
$ sudo update-alternatives --config java
```
するとこんなメニューが出てくるので
```
  Selection    Path                                            Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      auto mode
* 1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      manual mode
  2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      manual mode

Press <enter> to keep the current choice[*], or type selection number:
```
有効にしたいバージョンの数字を入れてenterでそのバージョンに変更されます。

# sdkmanを使う方法
aptで入らないバージョンやJDKを使いたい場合などは[sdkman](https://sdkman.io)を使う方法もあります。

skdmanは https://sdkman.io/install ここを参考にインストールされているものとします。

### インストールできるJDKの一覧
```bash
$ sdk list java
```

### インストール
```bash
$ sdk install java 17.0.5-amzn
```
※Correttoの17.0.5を入れる場合。
一覧のIdentifierの値を第三引数に指定することで特定のJDKがインストールできます。

### 切り替え
```bash
$ sdk use java 8.0.352-amzn
```

### 現在選択されているバージョン表示
```bash
$ sdk current java
Using java version 8.0.352-amzn
```

### デフォルトの指定
```bash
$ sdk default java 8.0.352-amzn
```
シェル起動時のデフォルトのバージョンを指定します。

# 方法別のメリットデメリット
まとめてみるとインストールの手間はあるもののsdkmanのほうが開発者向きな気がします。

## alternatives
* メリット
    * 特別なツールをインストールする必要がない
* デメリット
    * システム全体の設定が変わってしまうため、コンソールごとに違うバージョンを使うことはできない。

## sdkman
* メリット
    * シェルごとに切り替えられるため、別バージョンを使い分けることが可能。
    * いろいろなJDKが切り替えて使える。
* デメリット
    * sdkman自体のインストールが必要。
SageMakerで既存の学習済みモデルをS3から取得してデプロイする

# 背景
SageMaker関連の記事では、コードの中で学習させたモデルをそのままデプロイする
というようなサンプルコードを多く見かける。
例えば以下のように、モデル（コード中では`bt_model`）を定義して学習し、そのままその変数を使ってデプロイする（コード中では`bt_model.deploy`）というようなもの。
```python
# データの準備部分は省略
# モデルを定義
import boto3
region_name = boto3.Session().region_name
container = sagemaker.image_uris.retrieve("blazingtext", region_name)
bt_model = sagemaker.estimator.Estimator(container,
                                         role=role,
                                         instance_count=1, 
                                         instance_type='ml.m4.xlarge',
                                         input_mode= 'File',
                                         sagemaker_session=sess)
# パラメータを設定
bt_model.set_hyperparameters(mode="supervised",
                            epochs=10,
                            vector_dim=10,
                            early_stopping=True,
                            patience=4,
                            min_epochs=5)
# 学習
bt_model.fit(inputs=data_channels, logs=True)
# デプロイ
text_classifier = bt_model.deploy(initial_instance_count = 1,instance_type = 'ml.m4.xlarge')
```

しかし例えば、前日に学習させたモデルを翌日にデプロイするといった場合、
Pythonを一度終了してしまうと、モデルの変数（上記の場合`bt_model`)は消えているため、デプロイができない。
`bt_model`を再度学習するのはもちろん避けたい。
ではどうするか？

# 既存の学習済みモデルをS3から取得してデプロイする

こういった場合は、`sagemaker.model.Model`を使う。
学習されたモデルはS3上に出力されているので、それを参照してデプロイすることができる。
[公式ドキュメント](https://sagemaker.readthedocs.io/en/stable/api/inference/model.html#)

`image_url`はモデルを動かすための（学習にも使ったであろう）Dockerコンテナイメージ
`model_data`は学習したモデルが格納されているS3の場所（URI）
`role`はSageMakerを使うためのAWSのrole
`predictor_cls`はよくわからんけど必須。詳しくは[こちら](https://repost.aws/questions/QU6Cm7BTSlQ1GtLEzqVeGftQ/loading-and-deploying-a-previously-trained-sagemaker-xgboost-model)


```python
import sagemaker
# 既存のモデルを取得して、bt_modelに入れる
bt_model = sagemaker.model.Model(
    image_uri = sagemaker.image_uris.retrieve("blazingtext", "ap-northeast-1") 
    ,model_data = "s3://sagemaker-ap-northeast-1-****************************/model.tar.gz"
    ,role = "arn:aws:iam::*********************************"
    ,predictor_cls = sagemaker.predictor.RealTimePredictor
)

# bt_modelをデプロイする
text_classifier = bt_model.deploy(initial_instance_count = 1,instance_type = 'ml.m4.xlarge')
```

これで、以前に作成した学習済みモデルや、他人の作ったモデルをデプロイすることができます。

# おわり
終わりです。お疲れ様でした。
【CommonLisp】別パッケージの関数と同名の関数を定義したい

## 結論

shadowを使おう

```common-lisp:human.lisp
(provide :human)

(defpackage :human
  (:use :cl) ; 1. clでexportされているsymbolをすべてインターンする
  (:shadow :print) ; 2. こう書くことによってclのprintはhumanにインターンされない
  (:export :print))
(in-package :human)

(defun print () ; 3. そしてhumanでprintを定義することができる
  (cl:print "Hello, World!!")) ; 4. 修飾子をつけることでclのprintが利用できる
```
BINDに追加したレコードが引けない話

# はじめに
久しぶりにBINDでゾーンファイルを編集したら躓いたのでメモ。

# 作業前の状況とやりたかったこと

example.jpを例示ドメインとし、分かりやすくするためTTLとSOAの記述は省略しています。

```example.jp
      IN      NS      ns1.example.com.
      IN      A       192.168.254.1
```

今回追記しようとしていたレコードは次の通りです。


|名前|クラス|種別|値|
|---|---|---|---|
|subdomain|IN|CNAME|subdomain.example.com|
|sub|IN|TXT|"TEXT RECORD"|

# 設定後の状況

上記のことを踏まえて、下記のようにゾーンファイルを設定しました。

```example.jp
             IN      NS      ns1.example.com.
             IN      A       192.168.254.1
subdomain    IN      CNAME   subdomain.example.com
      sub    IN      TXT     "TEXT RECORD"
```

ゾーンファイルチェックでエラーが出ないことを確認して、BINDをリロードします。
その後、確認のためnslookupで確認しました

```
*** ns1.example.com が subdomain.example.jp を見つけられません: Non-existent domain
```

```
*** ns1.example.com が sub.example.jp を見つけられません: Non-existent domain
```

さて、どこが間違っていたのでしょう？

# CNAMEレコードの誤り
設定したかった値は `subdomain.example.com` ですが、この場合にはBINDのゾーンファイルで狭義のFQDN、つまり `subdomain.example.com.` と末尾にピリオド付きで指定する必要があります。
初回設定時の内容では `subdomain.example.com.example.jp.` を指定したのと同じ扱いになります。そんなものはない。

# TXTレコードの誤り
見かけ上の位置を揃えるために、レコードが半角スペースから始まっています。
つまりBINDでは実質的に下記のように解釈されるものと思われます。

|名前|クラス|種別？|値？|？？？|
|---|---|---|---|---|
|(なし)|sub|IN|TXT|"TEXT RECORD"|

クラスがインターネット(IN)以外のレコードになってしまっています。
見出しにTXTレコードの誤りと書いたな。あれは嘘だ。(などと)

# 正しい追記後の例示

```example.jp
             IN      NS      ns1.example.com.
             IN      A       192.168.254.1
subdomain    IN      CNAME   subdomain.example.com.
sub          IN      TXT     "TEXT RECORD"
```

# さいごに
BINDこわい。
【LINE Messaging API】テキストメッセージで絵文字を指定する方法

## はじめに
こんにちは！
この記事は[ミロゴス Advent Calendar 2022](https://qiita.com/advent-calendar/2022/milogos) 9日目の記事です。

今回は、LINE MessagingAPIでテキストメッセージを送る際の絵文字の指定方法とその際のTipsについて共有できればと思います。

## 絵文字の指定方法
[テキストメッセージ](https://developers.line.biz/ja/reference/messaging-api/#text-message)上での絵文字指定方法は以下のパターンがあります。

1. Unicord絵文字
2. LINE絵文字
3.  ~~LINE独自のUnicord絵文字~~　[※2022年3月をもって廃止](https://developers.line.biz/ja/news/2022/04/01/line-original-unicode-emojis-has-been-discontinued/)

それぞれの指定方法について以下で説明します。

## Unicord絵文字
Unicord絵文字については、単純に✨のようなUnicord絵文字をJsonの```text```内にベタ打ちで指定すればOKです。（Unicord絵文字は端末依存なので端末によってLINEトーク画面上での見え方が変わります。）

例：
```
[
    {
        "type": "text",
        "text": "こんにちは✨\n元気ですか？\n元気があれば何でもできます😍\n1・2・3・ダーーー✊"
    }
]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609800/b61a191f-f5e2-f9a5-db3d-965909dc4e33.png)
※```\n```はテキストメッセージの改行コードです。

## LINE絵文字
LINE絵文字を利用する際は少々厄介です。

LINE絵文字を指定する際はJson内にLINE絵文字オブジェクトの配列である```emojis```を指定します。
ただ、この```emojis```内の```index```（テキスト内の絵文字の位置）の値指定がとても間違いやすい……。

その際、以下のTipsを覚えておくとLINE絵文字を使ったJson作成がスムーズになります。
- ```index```の値は「絵文字がテキスト内の何文字目に来るのか」の値ではなく、「絵文字の前にテキストが何文字あるか」の値（＝ テキストの1文字目に絵文字が来る場合は```index```は```0```）である。
- 改行コード```\n```は1文字としてカウントされる。
- ```index```を指定しようとしている絵文字より前に異なる絵文字が指定されている場合は、前の絵文字（```$```）も1文字としてカウントされる。

例：
```
[
	{
		"type": "text",
		"text": "こんにちは$\n元気ですか？\n元気があれば何でもできます$\n1・2・3・ダーーー$",
		"emojis": [
			{
				"index": 5,
				"productId": "5ac21a18040ab15980c9b43e",
				"emojiId": "028"
			},
			{
				"index": 27,
				"productId": "5ac22a8c031a6752fb806d66",
				"emojiId": "009"
			},
			{
				"index": 39,
				"productId": "5ac21e6c040ab15980c9b444",
				"emojiId": "023"
			}
		]
	}
]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609800/7a9564e7-ae99-e7cd-6e65-8c717d71a398.png)
[※送信可能なLINE絵文字リスト](https://developers.line.biz/ja/docs/messaging-api/emoji-list/)

## 最後に
ご覧いただきありがとうございました！
少々ニッチな内容でしたが、少しでも多くの方のお役に立てれば幸いです。
シニアエンジニア必見：ファシリテーション力の向上のさせ方

CTO，VPoE、エンジニアマネジメント職の人々にとって人を動かすためのファシリテーテーション力は重要なスキルです。その割に、あまりファシリテーション力向上について意識をもってる方が少なく思います。
![25102595_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/e6c79176-b22a-7532-fdb9-44a07d21b917.jpeg)
# ファシリテーション力とは
ミーティングを円滑に進めるための司会の役割です。参加メンバーの意識を高めて、発言の量を増やしながら、発散しない様にまとめていき、最後は、全員で合意できる結果までもっていく事が必要となります。
この役割の人をファシリテーターと呼びます。ある程度の企業になると経営会議に外部のファシリテーターを参加させる企業もありますが、エンジニアの部分は、分かりにくい部分が大きいのでエンジニアマネジメント職が適切なファシリテーターになれる必要があります。

# 最初は、目的の共有
ミーティングの目的を参加者全員で共有する事から始めます。ここが揃ってないと議論が発散しますし、目的を共有しても発散する事が多々あります。最初に全員でしっかりと目的を共有しましょう。
例えば、会議の名前が「開発効率化ミーティング」だった時に、
- ある人は、開発においてのリソースの効率化だと思っている
- ある人は、開発のコストの効率化だと思っている
- ある人は、プログラミングの効率化だと思っている

どの部分についての効率化について話合うのが目的なのかをしっかりとファシリテーターから伝えます。全部の話をしたい時は、それを明確するのも必要です。
ある会議のやり方で、最初に全員でミーティングが終わった時に自分を発表させる手法もあります。これも良いですが、個人的には宗教っぽくて嫌いです。

# 時間割を明確にする
目的と同じで時間割も重要です。気がついたら終了時間になってしまうという経験は良くあると思いますが、最悪です。最後でドタバタして何も決まらないミーティングもあります。議論するのが目的であれば、それも良いのですが、基本的には時間割を明確にしてファシリテーターから伝えましょう。これは段取りを理解してもらうのと時間までに結論を出さねばならないと認識してもらうためです。
更にファシリテーターは、場の状況をみながら、時間割も動的に変更させます。ここはもう少し深堀りが必要そうだと思えば、後工程を調整します。ここの深堀り必要具合のジャッジが必要なため、エンジニアマネジメント職がファシリテーション出来るのが良いです。

# 発言しやすい雰囲気を作る
ファシリテーターから質問をしたり、あえて難題とか、反対意見とかをふって、それに対して答えてもらいます。あえて議論を発散させる事で発言しやすい雰囲気を作る事が出来ます。絶対に無理でしょ、みたいな話をふると反対意見から発言がしやすくなる訳です。
僕は、あえて会議室を歩き回ります、ファシリテーターが前に座って皆を見てると、話しにくい雰囲気も出ます。歩き回って、上長がいないフラットなメンバーのみの雰囲気を出せます。

# 議論をまとめる
## 目的の案に絞る
発言が活発になってくると議論が目的とずれたりします。目的とずれた案は捨てるのではなく、棚上げして、後日検討項目とします。
## 時間軸をあわせる
目的に沿っていても、時間軸に合わない案も出来てきます。半年間の事を決めたいのに２年くらい掛かりそうな案が出た場合は、こちらも棚上げして、後日検討項目とします。
## 可能性揃える
発言しやすい雰囲気になると、突飛なアイデアも出てくる事があります。実現可能があまりにも低そうな案については、一旦、棚上げして、後日検討項目とします。但し、時間が立ったり、会社のステージによっても可能性が変わり突飛なアイデアでも無くなったりしますし、可能性が低いとジャッジした事が間違いの可能性もあります。ここは慎重にジャッジしましょう。

# 終わりは、実行段階まで持っていく
最後は必ず実行段階まで持っていきましょう。
- 役割を決める
- スケジュール
- ゴール
これらが決まったらミーティングは成功です。但し、役割の担当者の腹落ちにも注意が必要です。流れで担当者になってしまったり、ゴールを理解していない場合もあります。最後に担当者の腹落ち状況をチェックしましょう

# 最後に
ファシリテーションのポイントいかがでしょうか？　多分、僕はファシリテーションは下手ではないと思ってます。このファシリテーションスキルですが、海外でもある程度通用すると思います。前職でモンゴルエンジニアでも同様にやりましたが、使えました。
エンジニアマネジメント職の方は、適切なファシリテーションで最大のアウトプットを目指してください
RPGにも for each ! 

ついに、「 `RPG` にも **for ～ each** が来ましたよ～！」
使用できるのは、**V7R5 ,V7R3+PTF 以上** です。その他の言語でもよく見るので、言わずもがなですが、使い方は次の通り。

```rpgle:QII0200R
D*- ---<< 変数定義    >>-----*
D ROW             DS                  QUALIFIED
D  ID                            5S 0
D                                1A
D  NAME                         26A
D*
D ROWS            DS                  LIKEDS(ROW)
D                                     DIM(05)
D*
C*- ***************************************************************
C*- *  メインロジック                                            **
C*- ***************************************************************
C                   Z-ADD     *ZERO         ID                5 0
C*
C*-  ｆｏｒ～ｅａｃｈで配列を処理（値セット）
C                   FOR-EACH  ROW IN ROWS
C                   ADD       1             ID
C                   EVAL      ROW.ID      = ID
C                   EVAL      ROW.NAME    = ' 名前 _' + %EDITC(ID :'X')
C     ROW           DSPLY
C                   ENDFOR
C*
C     ROW           DSPLY
C*
C*-  ｆｏｒ～ｅａｃｈで配列を処理（値参照）
C                   FOR-EACH  ROW IN ROWS
C     ROW           DSPLY
C                   ENDFOR
C*
C                   SETON                                        LR
C                   RETURN
```

これの結果は、以下のスクショになります。
**注意**は、
他の言語とは違い、変数 `ROW` は `for-endfor` スコープを外れても、最後の `ROW` の値を保持している（※`DSPLY 00005` の2回目）。
変数 `ROW` 参照渡しでは無いので、値の保存には向かない点です。
`FOR-EACH &ROW ROWS` とかもプラスで出来たら素敵なんだけどね。まぁ、そこは贅沢、`%ELEM` を記述しなくなっただけでも良しとしましょう。

![2022-12-02_161146.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/cbba1d79-19a7-9576-e7ed-ef283bc58ba6.png)
ふとしたときに便利なネットワーク機器自身からのsnmp walk

#### こちらの12/2 (2日目)の記事になります

https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output

----

ネットワーク機器の監視でいまだに根強く使われるSNMP
object Nameについて私が利用頻度の高いものをまとめていきたいと思います

#### 迷子になった時の参考にしてください（未来の自分）

さくっと確認したいとき、別のサーバから、`snmp walk`などを用いてOIDを指定してもよいのですが、ネットワーク機器自体でさくっと確認したい時にコマンドで確認することができると便利です

JUNOSであれば`show snmp mib walk object` 、CiscoのIOS系であれば `show snmp mib object`でネットワーク機器自体で確認することができます
```ruby:command
#JUNOS
show snmp mib walk object

#IOS
show snmp mib object
```
objectの箇所を自分が取得したいものに書き換えてください

### 標準MIB
----


#### system
>このobject の子objectとしては、ホスト名や起動時間などが含まれます
- https://oidref.com/1.3.6.1.2.1.1

|Object Name|説明|活用用途|OID|
|:--:|:--:|:--:|:--:|
|sysDescr|システムのハードウェアの完全な名前とバージョンの識別|OSの種類やバージョンを取得|1.3.6.1.2.1.1.1
|sysObjectID|システムの標準的な識別|ネットワーク機器の型式を取得|1.3.6.1.2.1.1.2
|sysUpTime|起動してからの時間（100 分の 1 秒単位）なので、0.01を乗じてあげると扱いやすい|起動時間を取得|1.3.6.1.2.1.1.3
|sysName|ノードに管理上割り当てられた名前|ホスト名を取得|1.3.6.1.2.1.1.5

```ruby:sample
foo@bar> show snmp mib walk sysObjectID
sysObjectID.0 = jnxProductNameMX240
```


#### Interfaces
>インターフェイス オブジェクト グループには、ネットワーク デバイスの各インターフェイスに関する情報が含まれています
- https://oidref.com/1.3.6.1.2.1.2


|Object Name|説明|活用用途|OID|
|:--:|:--:|:--:|:--:|
|ifNumber|機器に存在するネットワーク インターフェイスの数|認識されているインターフェースの総数を取得|1.3.6.1.2.1.2.1	
|ifTable|インターフェイス エントリのリスト。エントリの数は、ifNumber の値によって指定される|これ自体は使わないが子を多く使うため記載|1.3.6.1.2.1.2.2

##### ifTable
|Object Name|説明|活用用途|OID|
|:--:|:--:|:--:|:--:|
|ifIndex|各インターフェイスを表す一意の値|zabbix等で取得するインターフェースを指定するために利用|1.3.6.1.2.1.2.2.1.1
|ifDescr|インターフェイスに関する情報を含むテキスト文字列|ge-0/0/0等、人が認識できる情報へifIndexを紐づけた結果を取得|1.3.6.1.2.1.2.2.1.2
|ifPhysAddress|プロトコル層のインターフェイスのアドレス(MACアドレス)|インターフェースのMACアドレスを取得。L2障害等でラーニング対象を確認する等で利用|1.3.6.1.2.1.2.2.1.6
|ifAdminStatus|インターフェイスの設定されている状態|状態の変化を監視|1.3.6.1.2.1.2.2.1.7
|ifOperStatus|インターフェイスの現在の動作状態|状態の変化を監視|1.3.6.1.2.1.2.2.1.8
|ifLastChange|インターフェイスが現在の動作状態に入ったときの sysUpTime の値|状態の変化を監視|1.3.6.1.2.1.2.2.1.9
|ifInOctets|フレーミング文字を含む、インターフェイスで受信したオクテットの総数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.10
|ifInDiscards|エラーが検出されなかったにもかかわらず、破棄されるように選択されたインバウンド パケットの数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.13
|ifInErrors|上位層プロトコルへの配信を妨げるエラーを含むインバウンド パケットの数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.14
|ifOutOctets|フレーミング文字を含む、インターフェイスから送信されたオクテットの総数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.16
|ifOutDiscards|エラーが検出されなかったにもかかわらず、破棄されるように選択されたアウトバウンド パケットの数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.19
|ifOutErrors|エラーのために送信できなかったアウトバウンド パケットの数。|状態の変化を監視|1.3.6.1.2.1.2.2.1.20


```ruby:sample 抜粋
foo@bar> show snmp mib walk ifDescr
ifDescr.1     = fxp0
ifDescr.4     = lsi
ifDescr.5     = dsc
ifDescr.6     = lo0
ifDescr.7     = tap
ifDescr.8     = gre
ifDescr.9     = ipip
ifDescr.10    = pime
ifDescr.11    = pimd
ifDescr.12    = mtun
ifDescr.13    = fxp0.0
ifDescr.16    = lo0.0
ifDescr.17    = em0
ifDescr.18    = em0.0
ifDescr.21    = lo0.16384
ifDescr.22    = lo0.16385
ifDescr.23    = em1
ifDescr.24    = em1.0
ifDescr.501   = cbp0
ifDescr.502   = demux0
ifDescr.503   = esi
ifDescr.504   = irb
ifDescr.505   = jsrv
ifDescr.506   = jsrv.1
ifDescr.507   = pip0
ifDescr.508   = pp0
ifDescr.509   = rbeb
ifDescr.510   = vtep
ifDescr.511   = lc-0/0/0
```

**ちょっとした確認のときなどに、使っていきましょう！**
Ubuntu 22.04 - BIND インストール

## 前提
前回まで WordPress をインストールするために Nginx, MariaDB, PHP をインストールしてきました。やっと WordPress をインストールできるぞー！っといった状況ですが、調べていると先に DNS サーバを用意した方が良さそうなので、ここで DNS サーバを構築します。
## 環境
Ubuntu 22.04
BIND 9.18.1
## 設定
新しく仮想マシンを用意します。この辺の記事を参考にするとよいです。

https://qiita.com/akikito/items/d30d85d4d05694887726

https://qiita.com/akikito/items/a31c4c2b38953d11b999

https://qiita.com/akikito/items/b081164d83476c38cf8c

ネットワークに接続できるようになったら、BIND をインストールします。
```
$ sudo apt install bind9
```
ステータスを確認します。`active (running)`になってればOK
確認コマンドで`systemctl status bind9`が使えないので`systemctl status named`を使ってるケースもあったみたいだけど、ここでは使えた。
```
$ sudo systemctl status bind9
```
バージョンを確認しておこう。結果からいうと、こっちは`bind9 -v`が使えなかったｗ
```
$ named -v
BIND 9.18.1-1ubuntu1.2-Ubuntu (Stable Release) <id:>
```
中身はこんな感じ。
```
$ sudo ls /etc/bind/
bind.keys  db.127  db.empty  named.conf                named.conf.local    rndc.key
db.0       db.255  db.local  named.conf.default-zones  named.conf.options  zones.rfc1918
```
`named.conf`が BIND 設定ファイル。ここから設定していなかいといけない。
AZ-900の試験を英語で受けることにした

# はじめに
はじめまして、こんにちは。
駆け出しどころかまだ卵からかえってすらいない、日々研修に励んでいる見習い研修エンジニアです。

私はバックエンドを中心としたフルスタックのweb applictionエンジニアを目指している卵なのですが、Azureの基礎的な知識を最低限固めておきたいと思い試験を受けることにしました。

個人的にカタカナよりも英語の方が得意なのと、別言語から翻訳された日本語よりも英語の方が分かりやすいと感じるため、英語での試験を受けることに決めました。

せっかくなので勉強ついでに、自身の勉強の記録用、そして自身の後からの復習用でまとめて記事にしていこうと思います。

Qiitaに何かしら投稿しようと思い始めてから４か月もたってしまいましたが、ドキドキの初投稿思い切ってしちゃおうと思います。
エンジニアとして色々とつたないですし、英語中心の記事になってしまうとは思いますが、お手柔らかにお願いいたします。

日本語での情報が欲しい方は、こちらのサイトを参考にしてみてください：
Microsoft Azure Fundamentals 新試験範囲(日本語翻訳版)
https://qiita.com/fsd-jume/items/4ac66894d0b656fed466

# 目次
- [はじめに](#はじめに)
- [目次](#目次)
- [AZ-900 Domain Area](#az-900-domain-area)
- [Study Plan](#study-plan)

<a id="#az-900-domain-area"></a>
# AZ-900 Domain Area

According to the Microsoft official website, the exam consists of three domain areas with following weights:
* Describe cloud concepts (25-30%)
* Describe Azure architecture and services (35-40%)
* Describe Azure management and governance (30-35%)

<a id="#study-plan"></a>
# Study Plan
At least an hour per day will (hopefully) be spent for the exam preparation until 21nd of Feburary in Japan time as the exam will be on the following day.

Based on the areas provided above, Microsoft Learning Path will be used as the exam preparation materials, and these are the courses that will be taken:

  * Microsoft Azure Fundamentals: Describe cloud concepts
    * Describe cloud computing

  * Azure Fundamentals: Describe Azure architecture and services
    * Describe the benefits of using cloud services
    * Describe cloud service types
    * Describe the core architectural components of Azure
    * Describe Azure compute and networking services
    * Describe Azure storage services
    * Describe Azure identity, access, and security

  * Azure Fundamentals: Describe Azure management and governance
    * Describe cost management in Azure
    * Describe features and tools in Azure for governance and compliance
    * Describe features and tools for managing and deploying Azure resources
    * Describe Azure compute and networking services
    * Describe Azure storage services
    * Describe Azure identity, access, and security
    * Describe cost management in Azure
    * Describe features and tools in Azure for governance and compliance
    * Describe features and tools for managing and deploying Azure resources
    * Describe monitoring tools in Azure
強化されたデバッグ・オプション

プログラマとしては負けている様で、デバッガーには頼りたくないと常日頃思っていますが、それでも使う機会はあるもので、そんなRPGのデバッガーが **V7R5(V7R3 +PTF以上)** で強化された模様。
追加されたオプションが `①DEBUG(*CONSTANTS)` と `②DEBUG(*RETVAL)`。
- `①DEBUG(*CONSTANTS)` はデバッグ中に名前付き定数の中身が参照出来る
- `②DEBUG(*RETVAL)`はプロシージャの戻り値が参照できる。上書き出来る

 個人的に①は「出来てなかったんだー」と思うくらいで、「D仕様書」を見れば判るからと言えばそうだが、いちいちソースを移動する手間を考えるとそれはそれで便利。
②は以前から「出来ない事が不便だと」思っていました。戻り値を変数で受けて、`DUMP` したりする事を考えるとコレは便利！

以下、使用例

```rpgle:QII0190R
H DFTACTGRP(*NO) ACTGRP(*NEW)
H*- *CONSTANTS …定数ををデバッグ時参照する
H*- *RETVAL    …プロシージャの戻り値を「 _QRNU_RETVAL 」で表示／変更する
H DEBUG(*CONSTANTS : *RETVAL)
D*- ---<< 変数定義    >>-----*
D MSG             S             40A
C*- ***************************************************************
C*- *  メインロジック                                            **
C*- ***************************************************************
C                   EVAL       MSG        = SUBPROC1()
C     MSG           DSPLY
C*
C                   SETON                                        LR
C                   RETURN
P*- ***************************************************************
P*- *  サブプロシージャ                                          **
P*- ***************************************************************
P SUBPROC1        B
D SUBPROC1        PI            40A
D*
D*- ---<< 定数定義    >>-----*
D C#STR           C                         ' 名前付き定数 '
D*- ---<< 変数定義    >>-----*
D RET             S             40A
C*
C                   EVAL      RET         = ' 【変更前】 '
C                                         + C#STR
C*
C                   RETURN                  RET
C*
P                 E

```

デバッグする場合は、コンパイル時のオプションに `DEBGVIEW(*ALL)` 等を付与して下さい。

## 定数の参照

まず、上記PGMの実行結果は DSPLY命令で「**【変更前】名前付き定数 **」と表示されます。![2022-12-02_150955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/9853cc57-adfa-869e-0754-bf250ad5e838.png)

次に `STRDBG` でデバッグを開始して、適当な停止点で **名前付き定数** を「F11」で参照すると中身を確認することが出来ます。
![2022-12-02_151413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/4fc423f4-d8d1-7851-dace-4d7e1ef83985.png)

## 戻り値の参照及び変更

更に、プロシージャの最終地点に停止点を追加します。すると戻り値を返却する直前で停止し、特殊変数
「**_QRNU_RETVAL**」を介して、プロシージャの戻り値を確認することが出来ます。

![2022-12-02_151825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/14a4901f-8755-ad39-8e28-0d70d885ab10.png)

この特殊変数「**_QRNU_RETVAL**」をEVALで値変更すると、プロシージャの戻り値が変更されます。

![2022-12-02_151930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/732c988b-e070-cdd6-3f1f-27f77f246ed1.png)

![2022-12-02_152110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/2b18a92f-a307-96eb-3067-d09c76a503f4.png)

プロシージャの戻り値が見られるのは便利なのですが、この特殊変数名「**_QRNU_RETVAL**」は絶対に忘れそうなので、IMEにでも登録しておきましょう！
【Vercel】HobbyプランのAPIルート（Serverless Function）でハマった話

## はじめに
Next.jsにはAPIルートという機能があり、Next.jsを用いてAPIの実装が可能です。
APIルートはVercelでServerless Functions機能として位置しており、Next.jsだけでなくNode.jsやPythonなどの言語もサポートしています。

今回はAPIルートについて説明するわけではないので、詳しく知りたい方は下記から確認してください。
- [API Routes: はじめに | Next.js](https://nextjs-ja-translation-docs.vercel.app/docs/api-routes/introduction)
- [Serverless Functions – Vercel Docs](https://vercel.com/docs/concepts/functions/serverless-functions)
- [Supported Languages for Serverless Functions](https://vercel.com/docs/concepts/functions/serverless-functions/supported-languages)

## HobbyプランのServerless Functionsの制限について
[料金プラン](https://vercel.com/pricing)ではなく[Limitsページ](https://vercel.com/docs/concepts/limits/overview)に記載があり、HobbyプランではServerless Functionsは12個までしかデプロイできない記載があります。
![スクリーンショット 2022-12-01 18.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/a96e8702-0c3f-1c0a-46c1-da887f407c33.png)
*※2022年12月2日時点*

ただし、Next.jsについては下記のように単純にServerless Functionsを12個超えたとしても、その制限にかかるわけではないです。

> In the case of the "Serverless Functions Created per Deployment" limit, only dedicated Lambdas are counted as one Serverless Function. With Next.js, Vercel will automatically combine as many Serverless Functions as possible into a single Lambda, as mentioned in bundling serverless functions.

### 実際に試してみる
まずはNext.jsのLPより`nextjs-boilerplate`をVercelへデプロイしてみます。
デプロイのログを確認してみると、`λ`のマークが付いてるものがServerless Functionsということがわかります。
![スクリーンショット 2022-12-02 12.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/94006a5f-a4c1-591e-cf56-3fa02c0057da.png)

上記にも記載の通り、Next.jsでは単純に`λ`が12個超えたところで制限にかかるわけではないですが、制限を超えると下記のようなエラーメッセージが表示され、デプロイエラーとなります。
![スクリーンショット 2022-12-02 13.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/b14548db-154d-5795-b543-aea93948fa58.png)

## ここからが本題
普段、Next.jsを用いた開発をするとき、ルートに`/api`というディレクトリを作ってバックエンドのAPIを叩く用のファイルを集約しています。
この状態でVercelにデプロイすると`pages/api`でなく`/api`の中身まで、すべてServerless Functionsと識別されてしまい、12個を超えるファイルが配置されていた場合、上記と同じエラーが表示されてしまいます。

デプロイのログを見てるとログの最初の方に下記のワーニングが表示されてることが確認できます。
![スクリーンショット 2022-12-02 13.42.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/b6ded88f-12ad-98c4-2a63-98372cde4561.png)

要するにNext.js以外の言語が`/api`のディレクトリを使用するので、Next.jsでも同様に`/api`ディレクトリ内のファイルがServerless Functionsとしてカウントされてしまったようです。

### 解決策
`/apis`に変更してエラーを回避しました。

## まとめ
Vercelを利用する際には事前に[Limitsページ](https://vercel.com/docs/concepts/limits/overview)を確認して、要件に合うか確認したほうがよさそうですね。

## 最後に
### GoQSystemでは一緒に働いてくれる仲間を募集中です！
ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site/?qiita=9f7ecbb8e424b86cae6c
AG Gridという表ライブラリ

# 概要
https://www.ag-grid.com/

AG Gridは表ライブラリです。

生JavaScript/Angular/Vue.js/Reactに対応しており、
英語ではありますが豊富なドキュメントが整備されています。

拡張性が非常に高く、ライブラリ使っているからこの機能はできないよね？
ってのが割と無いです。

顧客に無茶な要求をされても対応できてしまうくらい
柔軟性が高いライブラリだということですね。

![スクリーンショット 2022-12-02 15.36.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360072/0d7bff4a-da94-c41b-04d9-19f32406d8cc.png)

# 使い方
インストール方法はドキュメントを参考にしてください。
この記事ではVue.js(3系)での利用方法の一例を解説します。

```vue
<template>
  <ag-grid-vue
    :columnDef="columnDef"
    :rowData="rowDataList"
  />
</template>

<script setup lang="ts">
import { AgGridVue } from 'ag-grid-vue3'

/** カラム設定 */
const columnDef = ref<ColDef[]>([
  { field: 'name' },
  { field: 'age' }
])
/** 表に表示するデータ */
const rowDataList = ref<RowData[]>([
  {
    name: 'hayashi',
    age: 28
  },
  {
    name: 'rinyu',
    age: 5
  }
])
</script>
```

 カラム設定の`field`はフィールド名（カラム名）で、
カラム名と同じプロパティ名で宣言された`rowData`内の要素を
表のセル内に描画してくれます。

ヘッダー名をつける時は、
カラム設定にこのように追加します。

```typescript
/** カラム設定 */
const columnDef = ref<ColDef[]>([
  {
     field: 'name',
     headerName: '名前'
  },
  {
    field: 'age',
    headerName: '年齢'
  }
])
```

# コンポーネント埋め込み
表のセル内にVueコンポーネントを埋め込むようなこともできます。

```typescript
import DeleteButton from 'src/components/DeleteButton.vue'

/** カラム設定 */
const columnDef = ref<ColDef[]>([
  {
     field: 'deleteButton',
     headerName: '削除',
     cellRenderer: DeleteButton
  }
])
```

# おすすめ
他にも色々できることがあるので、
プロジェクトの要件に合うようであれば
是非利用してみてください。
水分代謝量を予測できるようになったらしいのでWEBアプリとして実装した

## TL;DR

人の体から毎日何㍑の水分が出ていくかを計算できるようになったらしい。  
誰でも簡単に計算できるwebサービスにしてみた。  
https://canid-56.github.io/water-metabolism/

## 経緯

人の体の60%は水分ということは分かっていたが、毎日どの程度の水分が出たり入ったりするかは分かっていなかったらしい。  
しかも、自分の体格や気象条件などから個人の水分の代謝量を計算できるらしい。  
自分が毎日どれだけの水分を失っているのかを知れれば、毎日どれだけ水分を摂取する必要があるかを何となく知る事ができるので良いですね。  

> ソース : 『ヒトの体の水の代謝回転量を予測する式を世界で初めて発明 ～23カ国5604人を対象とした国際共同調査の結果から～』 国立研究開発法人 医薬基盤・健康・栄養研究所  
> https://www.nibiohn.go.jp/information/nihn/2022/11/008211.html
> 論文 : "Variation in human water turnover associated with environmental and lifestyle factors", Science  
> https://www.science.org/doi/10.1126/science.abm8668


## 計算式  
以下の式が水分代謝量の計算式とのこと。たぶん簡単な線形回帰モデルで推定したっぽいですね。

```
水の代謝回転 (㎖/日) = [1076×身体活動レベル] + [14.34×体重(kg)] + [374.9×性] + [5.823×1 日の平均湿度(%)] + [1070×アスリート] + [104.6×人間開発指数(HDI)] + [0.4726×標高(m)] – [0.3529×年齢の 2 乗] + [24.78×年齢(歳)] + [1.865×平均気温の 2 乗] – [19.66×平均気温(℃)] –713.1
```

変数は以下のような意味のようです。  
本人の要因はまあそうでしょうという感じ。  
環境の要因は、飽和水蒸気量的な話だと思います。  
社会的な要因は、発展途上国は肉体労働者が多いとかそういう理由だろうとのこと。

* 本人の要因
  * 性
    * 女性が0, 男性が1
  * 年齢
  * 体重
  * 身体活動レベル
    * 座位中心な場合 1.5、平均的な場合 1.75、高い場合 2.0
  * アスリート
    * 非アスリート 0、アスリート 1
* 環境の要因
  * 平均気温
  * 平均湿度
  * 標高
* 社会的な要因
  * 人間開発指数 (HDI : Human Development Index)
    * 先進国が0, 中間的な国が1, 発展途上国が2
    * ↓から調べることができる
    * https://hdr.undp.org/data-center/human-development-index#/indicies/HDI

基本的に各変数と水分代謝量は線形なので理解しやすいですね。  
年齢と平均気温は2次の項が入っているので、どういう関数系になるか描いてみます。  
簡単のために、変数は全て独立であると暗に仮定しています。また、年齢や平均気温が0である点を0としています。

```python
import numpy as np
import matplotlib.pyplot as plt
age = np.arange(1,91)
water_age = - 0.3529*age**2 + 24.78*age
plt.plot(age, water_age)
plt.xlabel("age")
plt.ylabel("water")
plt.show()
```
![water_age.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315348/92ea1512-e00e-61d4-b536-727ff1106e93.png)



```python
mean_temp = np.linspace(-10,30,100)
water_mean_temp = 1.865*mean_temp**2 - 19.66*mean_temp
plt.plot(mean_temp, water_mean_temp)
plt.xlabel("mean temp")
plt.ylabel("water")
plt.show()
```

![water_temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315348/ada81047-3319-5f42-4765-74f0e2ab32c9.png)


年齢については、30代後半の働き盛りをピークに40代からは代謝が落ちていくみたいです。  
平均気温は、基本的に加速して上がり続けるようです。飽和水蒸気の曲線と似ています。平均気温が5℃以下の時は傾きがマイナスになっていますが、そもそも平均気温が5℃以下になるような状況が少ないので、あまり気にしなくてもいいのだと思います。

## 実装

注意 : Bootstrap と Vue しか知らない雑魚が作ったページなので、だいぶダサいです。

* ソースコード
  * https://github.com/canid-56/water-metabolism
* デモページ
  * https://canid-56.github.io/water-metabolism/

## 注意

> ただし、ここで注意していただきたい点は、20 歳代男性で 1 日に平均 4.2ℓ の水分が失われるとしても、1 日 4.2ℓ の水を飲む必要はないということです。

体内で作られたり、水蒸気を呼吸したり、食事の中の水分である程度補うことができるということらしい。

## もっとやりたいこと

* 天気予報系のAPIからその日の平均気温と湿度を入れられるようにしたい
* 居住国からHDIを自動取得で割り振りたい
* GPSから天気やら標高やら居住国やらを読み取りたい
図書館への推薦図書一覧を楽に作りたい (CUI版,Perl)

サーバ構築演習の科目があります。最終課題は、なんらかの連携(Web)をするシステムを構築してみやう！というものです。

その課題のテーマ例として「図書館へ推薦する図書の一覧を作るのが面倒なので誰か作ってくれないかな〜」というのを書いておきました。

結局、そのコマンドライン版を自分で作りました。でも、グラフィカルなものは興味がないので誰かよろしく


## 仕様

- 目標 ... コマンドライン(CUI)版はGUI版とは目標が異なります
    - GUIは1個2個を処理する素人さんむけのもの (未実装)
    - このCUIは、数十個の推薦を一気に処理したいというもの (実装したもの)。バッチ処理といってもいいです
- 使い方(想定している運用方法)
    - あらかじめブラウザで推薦候補(数十個)をブックマークしておきます
    - ブラウザのブックマークを全部選択してコピーすればURL一覧がクリップボードに入ります
    - テキストファイルにクリップボードの中身を貼りつけます
    - 推薦図書一覧が1行1URLになったテキストファイルの完成です
    - このテキストファイルをプログラムで処理すると必須情報のまとめが表示されます
- プログラミング言語 ... テキスト処理なんだから、得意のPerlでいってみやう！
- 注意点/工夫点
    - 取得したデータ(HTML)はキャッシュするようにしました。つまりURLを見にいくのは最初の一回だけです
    - コマンドラインオプションで、出力モードを切り替えられます。テキストとCSVモードあり。デフォルトはテキスト
    - 取得するデータフォーマットはサイトごとに異なります。
      ここはサイトの数だけ造り込みが必要です。
      とりあえずAmazon(とラムダノート)だけ対応しています
    - すでに大学図書館に登録済みか？も確認します(ISBNで問い合わせ)


## 出力例

```
title  = 日本インターネット書紀 この国のインターネットは、解体寸前のビルに間借りした小さな会社からはじまった
isbn13 = 9784062189446
price  = 4730
exist? = yes
```


## コード見本

いまのところ約300行です。先頭のモジュールとメインループだけ書いておきます。


```
#!/usr/bin/env perl

use strict;
use warnings;
use Carp;
use utf8;
use FileHandle;
use File::Spec;
use File::Path;
use LWP::UserAgent;
use Encode qw(decode encode is_utf8);
use JSON qw/encode_json decode_json/;

our $cache_dir = "$ENV{HOME}/work/bookdb";

while (my $buf = <>) {
    chomp $buf;
    
    next     if $buf =~ /^\#/;    # ignore comments
    next unless $buf =~ /https/i; # ignore not HTTP/HTTPS lines
    
    my ($id, $flag, $data) = url_parse($buf);
    # 省略 ... $data を出力 ...
}

exit 0;
```
AWS認定クラウドプラクティショナー合格に向けて Day7

# 前回の内容
[AWS認定クラウドプラクティショナー合格に向けて Day6](https://qiita.com/Ayako_0224/private/e3c14f922625cf54b4d3)

# サポート系のサービス
## AWSサポートセンター
AWSのアカウント登録すると何かしらのサポートプランに自動で登録される
無料アカウントの場合はベーシックのサポートプランに登録される
ベーシックのサポートプランでは電話やチャットでの問い合わせができないため、サポートケースというものを作成して質問を作成する
AWS知識リソースという場所で自力で解決することもできる

### AWS知識リソース
- ナレッジセンター
    頻繁に寄せられる質問や要望が乗せられている
- AWSドキュメント
    ユーザーガイドやAPIなどのドキュメントが載っている
- 開発者フォーラム
    質問をして回答してもらえるStack overflowのようなもの
    現在はre:Postという代替サービスに移動するよう勧められる
- トレーニングと認定
    AWSの公式で提供しているトレーニングプログラムや資格の案内がされている

## 専門家の支援
AWS IQという仕組み
AWSにパートナー登録されている個人や企業からエキスパートを探しマッチングすることができる

## re:Post
先ほど紹介したAWS開発者フォーラムが廃止されこのre:Postに統合される予定
エキスパートに対して質問して回答を得ることができるコミュニティ
英語のみ対応

次の記事は➡︎[AWS認定クラウドプラクティショナー合格に向けて Day8](https://qiita.com/Ayako_0224/items/2efd9e496b3e53c50aea)