TECH PLAY

サイオステクノロジー(Tech.Lab)

サイオステクノロジー(Tech.Lab) の技術ブログ

524

こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 Red Hat 社は RHEL7 の Extended Life Cycle Support (ELS)、つまり RHEL7.9 のサポートが 4年間延長することが発表しました。 Announcing up to 4 years of Extended Life Cycle Support (ELS) for Red Hat Enterprise Linux 7 https://www.redhat.com/en/blog/announcing-4-years-extended-life-cycle-support-els-red-hat-enterprise-linux-7 SECCON Beginners CTF 2024 (初心者向けの、情報セキュリティ競技会) の日程が発表されました。 今年は 2024/6/15 (土) ~ 6/16 (日)、7 回目の開催となります。 SECCON Beginners CTF 2024 を開催いたします! https://www.seccon.jp/13/seccon_beginners/content.html 5/17、Linux Foundation Japan が「金融サービスにおけるオープンソースの状況 – 2023」 レポートを公開しました。 今後の動向が、ますます気になるところです。 Linux Foundation Japan、調査レポート「金融サービスにおけるオープンソースの状況 – 2023」を公開 https://codezine.jp/article/detail/19541/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2024年5月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
アバター
こんにちは、サイオステクノロジーの佐藤 陽です。 ChatGPT-4o が世間を賑わせていますね! 今日はそんな生成 AI を使いこなすための プロンプトエンジニアリング について解説していこうと思います。 思ったような回答得られないんだよなー もっと生成 AI をうまく使いこなしたいな といった方はぜひ最後までご覧ください。 なお今回は基礎編になります。 もう少し踏み込んだ内容については、続編を書こうと思っているのでこうご期待ください。 プロンプトエンジニアリングとは? NRI によると、以下のように定義されています。 AI(人工知能)から望ましい出力を得るために、指示や命令を設計、最適化するスキルのことです。ChatGPT などの生成 AI を使いこなすために注目されるようになりました。生成 AI は、命令(プロンプト)の出し方によって、出力されるコンテンツの質が大きく異なるため、より適切なものを入力するスキルが求められています。 出典: https://www.nri.com/jp/knowledge/glossary/lst/ha/prompt_engineering 生成 AI は様々な回答を行ってくれますが、こちらの命令によってその回答内容は様々です。 こちらが質の高い命令を行うことで、AI からも質の高い回答が返ってきます。 例えば、「ダイエットをしたいなぁ」と思った時に 1. 「痩せる方法を教えてください」 と聞くよりも 2. 「 あなたは優れたスポーツドクターで、痩せるための食事や運動方法について精通しています。 私は現在 30 歳の男で身長 170cm、体重 80kg あります。 1 年間で 5kg の減量をしたいと考えています。 痩せるために食事および運動についてのアドバイスをください 」 のほうがなんだか具体的なアドバイス貰えそうじゃないですか? 実際、AI の聞いてみたところ以下のような回答が得られました。 1. 痩せるためには、以下のポイントに注意してください: 適切な食事: バランスの取れた食事を摂ることが重要です。食事の量を減らし、野菜や果物、たんぱく質を豊富に含む食品を選びましょう。また、加工食品や糖分の多い飲み物は避けるようにしましょう。 適度な運動: 適度な運動を取り入れることで、カロリーを消費し脂肪を燃焼させることができます。有酸素運動(ウォーキング、ジョギング、サイクリングなど)や筋力トレーニングを行いましょう。 水分摂取: 水分は新陳代謝を促進し、体内の老廃物を排出する役割を果たします。適切な水分摂取を心掛けましょう。 心の健康: ストレスや不安は食欲や代謝に影響を与えることがあります。リラックスする時間を作り、良い睡眠をとることも大切です。 継続と忍耐: 痩せるためには時間がかかることもありますので、継続と忍耐が必要です。一時的なダイエットではなく、健康的な生活習慣を身につけることが大切です。 ただし、個々の体質や健康状態によって最適な方法は異なる場合がありますので、専門家に相談することをおすすめします。 2. 了解しました。以下に、食事と運動の面でのアドバイスをお伝えします。ただし、具体的なプランを作成するためには、より詳細な情報が必要ですので、専門家と相談することをおすすめします。 食事面のアドバイス: カロリー制限: 1 日の摂取カロリーを減らすことが重要です。適切なカロリー制限の範囲内で、栄養バランスの取れた食事を摂るようにしましょう。 高タンパク質食品: タンパク質は満腹感を与え、筋肉の維持・修復にも重要です。鶏肉、魚、豆類などの高タンパク質食品を積極的に摂取しましょう。 野菜と果物の摂取: 食事には野菜と果物をバランス良く取り入れましょう。食物繊維やビタミン・ミネラルの補給に役立ちます。 糖分と加工食品の制限: 砂糖や加工食品はカロリーが高く、満腹感を得にくくなる傾向があります。できるだけ避けるようにしましょう。 運動面のアドバイス: 有酸素運動: 有酸素運動は脂肪燃焼に効果的です。ウォーキング、ジョギング、サイクリングなどの有酸素運動を週に 3〜5 回行いましょう。30 分以上の運動を心掛けてください。 筋力トレーニング: 筋肉を増やすことで基礎代謝が上がり、脂肪燃焼効果が高まります。ウェイトトレーニングや体重を使ったエクササイズを週に 2〜3 回行いましょう。 毎日の活動量を増やす: 毎日の生活の中で積極的に動くように心掛けましょう。階段を使う、歩いて買い物に行くなど、日常生活に運動を取り入れることが大切です。 以上が一般的なアドバイスですが、個別の状況によって適した方法は異なります。身体の健康状態や運動経験に応じて、専門家の指導を受けることをおすすめします。 思った以上に 1.のケースでも色々なアドバイスをされて驚きですが 2.のケースの方がやはり具体的なアドバイスをもらえている感じがあります。 プロンプトエンジニアリングの重要性 「なーんだ、ただの詳しく聞けばいいだけじゃん」と思われる方もいる方もいらっしゃいますが 聞き方に関しても色々なテクニックがあり、それを使いこなすことによって得られる 回答の精度も大きく変わってくる のです。 以下のOpenAI社のセッション内でもこのプロンプトエンジニアリングの重要性が述べられています。 A Survey of Techniques for Maximizing LLM Performance  要約すると LLM の性能を最大化するには RAG や、Fine-tuning などの方法があるが、スタート地点としてはプロンプトエンジニアリングである。 常にプロンプトエンジニアリングから始めて、全員がこの原則を理解していることが重要である ということであり、このプロンプトエンジニアリングを疎かにしてはいけないことが分かります。 環境 今回は Azure OpenAI のサービスを利用していきたいと思います。 モデルは gpt-35-turbo-16k を利用します。 ChatGPT を利用したり、別のモデルを利用した場合でも、問題なくプロンプトエンジニアリングの効果は得られます。 ただし、得られる回答が異なる場合がありますので、その点ご了承ください。 概要 基礎知識 このような Chat サービスを利用する場合として、 人間:「〇〇ですか?」 生成 AI:「×× です」 と対話するような利用方法をよく見ます。 ただし、これに限らず生成 AI モデルは、プロンプトのテキストに続く可能性が最も高い一連の回答を行おうとします。 例えば以下のような例を見てみたいと思います。 プロンプト 織田信長は戦国時代の 回答 武将であり、日本の戦国時代に活躍した有名な武将です。織田信長は、1534 年に生まれ、1582 年に暗殺されるまでの短い期間で日本史上に名を刻みました。 信長は、尾張国(現在の愛知県)の戦国大名であり、その勢力を拡大して近畿地方を支配しました。彼は数々の戦術や戦略を用いて、他の大名や武将との戦いで勝利を収め、領土を拡大していきました。 必ずしも「〇〇ですか?」と聞かなくても、プロントの内容をくみ取り、回答をしてくれます。 これから出てくるテクニックもこの基礎知識を活かす部分があるので、是非理解しておいてください。 Instructions 一般的によく使われる「 Instructions(命令) 」のテクニックです。 簡単な例と複雑な例の 2 つを挙げます ・簡単な例 プロンプト 会社を紹介するメッセージを考えてください。 回答 ご挨拶いたします。私たちの会社は、革新的なソリューションを提供するテクノロジー企業です。 私たちは、お客様のビジネスの成長を支援するために、最新の技術と専門知識を駆使しています。 私たちの強みは、独自のアプローチと柔軟性にあります。 お客様のニーズに合わせてカスタマイズされたソリューションを提供し、より効率的で効果的なビジネス運営をサポートします。 また、常に最新のトレンドやテクノロジーの動向に目を向け、お客様に最先端のソリューションを提供することをお約束します。 ・複雑な例 プロンプト 会社を紹介するメッセージを考えてください。会社の Vision と成り立ちに関する説明を加えてください。 回答 ご挨拶いたします。私たちの会社は、お客様のビジネスを革新し、未来に向けた成長を支援することを使命としています。 私たちのビジョンは、世界中の企業と個人が持つ潜在能力を最大限に引き出し、持続可能な社会の実現に貢献することです。 私たちの会社は、創業以来、革新的なソリューションを提供するために努力してきました。 過去の成功から得た経験と知識を活かし、常に最新のテクノロジーとトレンドに目を向けながら、お客様のニーズに合わせたカスタマイズされたソリューションを提供しています。 こうすることで、より求めている回答に近づくことができます。 要するに、 「具体的に質問してね!」 ということだと思います。 Primary Content Primary Content は、プロンプトとして与えた内容自体に処理をしてもらうテクニックです。 プロンプトとして与えるテキスト自体が回答のコンテンツになっているため、Primary Content という名称がついていますね。 エンジニアだとコードの変換とかで使われるかもしれません。 プロンプト 以下の C#のコードを TypeScript に変更してください。 public string Hello() {     return "Hello world"; } 回答 以下が、C#のコードを TypeScript に変換したものです。 public hello (): string {       return "Hello world" ;   }   以上が、C#のコードを TypeScript に変換したものです。 TypeScript では、関数に戻り値の型を指定するために string を追加しています。 また、public キーワードは TypeScript でも使用可能です。 コードの変換を正しく行ってくれました。 他にも、 プロンプトとして与えた 文章の要約 や、 翻訳(日本語 → 英語等) などにもよく使われるテクニックかと思います。 Examples Examples は、 few-shot と呼ばれるテクニックの基本にあたるものです。 few-shot 等の具体的な手法はまた続編で取り上げたいと思うので、今回は基本的な部分だけご紹介します。 (早く知りたい!という方は弊社 武井さんの 記事 をご覧ください。) プロンプトの内容として事前に複数の例を伝えておき、その例に沿って回答してもらうテクニックになります。 プロンプト りんご:赤 みかん:オレンジ ぶどう:紫 バナナ: 回答 黄色 こんな感じですね。 プロンプトから「果物:色」という法則を理解し、バナナの色の回答をしてくれています。 Cue 次の Cue は、プロンプトの回答の出力を誘導する方法です。 今回は例としてwikipedia から 織田信長 の情報を引っ張ってきて、その内容を要約してもらうことにします。 wikipediの[概要]の部分をプロンプトの暴投として与え、それを要約してもらうことにします。 なお、この時に回答の出だしを指定しました。 プロンプト [概要...] 上記の内容を要約してください。 また以下の文章から始めてください。 織田信長は桶狭間の戦いにおいて 回答 織田信長は、桶狭間の戦いにおいて駿河の今川義元を撃破し、尾張の統一を進めました。彼は尾張守護代の...(略) 指定した通りの出だしで回答を得ることができました。 このような指定をすることで、自分が得たい回答により近づくことができそうです。 なお、参考にした ドキュメント には、「また以下の文章から始めてください。」というワードがなくても実現できそうでした。 が、手元で [概要...] 上記の内容を要約してください。 織田信長は桶狭間の戦いにおいて とプロンプトを実行した場合は、出だしを無視して回答が行われてしまいました。 基礎知識のところで述べた部分とも相反する気もするのですが、日本語として何か影響があるのかもしれません。 Supporting content こちらは、プロンプトの回答に影響を与えるような情報を与えてあげるテクニックです。 上で説明したPrimary Contentは、プロンプト自体がコンテンツでしたが 今回のSupporting contentはあくまで補助的な情報としてコンテンツを提供する形になります。 例えば以下のような形です。 ・Supportなし プロンプト 友人に赤ちゃんが生まれたのですが、出産祝いは何がいいですか? 回答 赤ちゃんの出産祝いとして選べるさまざまなアイテムがあります。以下は一部のアイデアですが、贈り手の好みや予算に合わせて選んでください。 ベビーギフトセット:ベビーケア用品やおむつなどがセットになったギフトセットは、便利で喜ばれるアイテムです。 おくるみやベビーブランケット:赤ちゃんが暖かく包まれるような柔らかいおくるみやブランケットは、実用的で可愛らしい贈り物です。 おもちゃ:赤ちゃんが遊べるおもちゃやぬいぐるみは、成長に合わせて楽しめるプレゼントです。 ベビーウェア:可愛らしいベビーウェアやボディスーツなども喜ばれるアイテムです。 赤ちゃんの成長の記録用品:記念日や写真を残せるフォトフレームやアルバムなど、赤ちゃんの成長の記録に役立つアイテムもおすすめです。 マタニティグッズ:ママのケアを考えて、マタニティ用品やリラックスグッズなどを贈るのも良いアイデアです。 また、赤ちゃんの性別や親の好みに合わせて、色やデザインを選ぶこともできます。最も大切なのは、心からのお祝いの気持ちを込めて贈ることです。 ・Supportあり プロンプト 友人に赤ちゃんが生まれたのですが、出産祝いは何がいいですか? 10月生まれで、予算は1万円以内です。 回答 友人の赤ちゃんの出産祝いとして、以下のアイデアがあります。 予算が1万円以内 であることを考慮し、可愛らしさや実用性を兼ね備えたアイテムを選んでみてください。 ベビーギフトセット:赤ちゃんのお風呂やスキンケア用品がセットになったギフトセットがあります。柔らかな肌触りのタオルやベビーソープ、ローションなどがセットになっているものを選ぶと良いでしょう。 ベビー服セット:可愛らしいベビー服のセットを贈るのもおすすめです。季節に合わせた素材やデザインを選ぶと良いでしょう。 例えば、10月生まれあれば、秋らしい柄や色合いの服を選ぶと喜ばれるかもしれません。 おしゃぶりやスタイセット:おしゃぶりやスタイ、ベビーバンドなどがセットになったアイテムも人気があります。可愛らしいデザインや柄が多く、実用的な贈り物となります。 ベビーブック:赤ちゃんの成長やマイルストーンを記録できるベビーブックは、喜ばれるギフトの一つです。写真やメモリーを残すことができ、将来の思い出となります。 おもちゃ:柔らかいぬいぐるみや手触りの良いおもちゃは、赤ちゃんの興味を引きます。音が鳴るおもちゃや触ったり握ったりできるものを選ぶと良いでしょう。 これらのアイデアは、予算内で可愛らしさや実用性を考慮したものです。友人の好みや赤ちゃんの特性に合わせて選んでみてください。 このように補助的な情報を与えてあげることで、生成AIの回答としてもその情報に沿った回答をしてくれます。 Best Practice これまで基本的なテクニックをつらつら書いてきました。 ただ困ったとことにプロンプトについて厳格なルール化ができるものではないですし、白黒はっきり良し悪しを決めれるものでもないです。 そこがプロンプトエンジニアリングの難しいところですね。 ただ、先ほどのOpenAIの動画やMicrosoftのページなどを見ると 基礎的な部分で気を付ける点としては 具体的に伝えること 分かりやすく伝えること 簡潔に伝えること 繰り返し伝えること 分割して伝えること 伝える順序 といった事かなと思います。 個人的な総括として、根底にある考えとしては 「丁寧に伝えること」 であると感じました。 小さな子供に物事を伝える気持ちでプロンプトを書くと、良い回答が得られるのではないかなと思いました。 まとめ 今回は生成AIを使いこなすための基本中の基本であるプロンプトエンジニアリングを取り上げました。 テクニックに関して曖昧な部分もあり、使いこなすのが難しい部分がありますが、基礎的な部分なので頭に入れておきたいところです。 もう少し踏み込んだ内容は続編に書きたいと思うので、こうご期待! ではまた! 参考 プロンプト エンジニアリングの概要 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 今からでも遅くない!プロンプトエンジニアリング入門 ~基礎編~ first appeared on SIOS Tech. Lab .
アバター
こんにちは!サイオステクノロジーの安藤 浩です。DB設計書の生成が容易にできるDBMLをご紹介します。DBMLの入門として、DBMLの書き方、ER図生成方法、Github actionsでCIを実行して閲覧する方法をご紹介させていただきます。 DBMLとは DBML は DataBase Markup Language の略でDB構造を定義するために設計された言語です。 DB構造に焦点を当てており、可読性の高い言語です。 dbdiagram.io や dbdocs.io などを利用することでDBドキュメントの生成が可能です。 コードベースで図を生成できる点でPlantUMLと似ていますね。 DBMLの書き方 テーブルの書き方 まずはテーブルの定義の例をもとにDBMLの記法を紹介していきます。users というテーブルを作成してみます。コードは以下のようになります。 Table users {   id integer [pk]   first_name varchar   last_name varchar   email varchar [not null]   password varchar [note: 'Hashed password']   created_at datetime [not null, default: `now()`]   updated_at datetime     Indexes {     email [unique, name: "ui_users_email"]   }   Note: 'table: users' } 上記のテーブル定義を dbdiagram.io の左側のコード記載部分に張り付けると右側にプレビューが表示されます。 以下は dbdiagram.io でのプレビューをした時の表示です。(Noteの箇所は説明のため加工しています) (1) Table {テーブル名} でテーブルを定義します。 (2) {カラム名} {データ型} [{設定}]  という書き方でカラムを定義します。id の箇所の [pk] はプライマリキーを示しています。 {設定} の箇所には以下の属性が記載できます。カンマ区切りで複数可能です。 pk または primary key : プライマリキー unique : ユニークキー null または not null : Null 許容かNull 非許容 default : デフォルト値 increment : オートインクリメント note : メタデータとしてのメモ (3) 特定のカラムにメモを書けます。dbdiagram.io ではカラムにフォーカスが当たるとメモが表示されます。 (4) デフォルト値を設定することができます。 (5)インデックスの定義方法です。name に付けたいインデックス名を記載することでインデックスが作成されます。Noteはテーブルのメモとして記載できます。ここでもdbdiagram.io ではテーブル名の箇所にフォーカスが当たるとメモとインデックスが表示されます。 リレーションシップの書き方 さらに上記に倣い、profiles というテーブルを定義してみます。 Table profiles as prof {   id integer [pk]   user_id integer   bio varchar   website varchar   email varchar   created_at datetime [not null, default: `now()`]   updated_at datetime   Indexes {     user_id [unique, name: "idx_profiles_user_id"]   } } Table {テーブル名} as {エイリアス名} でエイリアス名が利用できます。 users と profiles に1対1のリレーションシップを作成したい場合は以下のように記載します。 Ref fk_profiles_user_id_users_id : profiles.user_id - users.id このように記載することで以下のように外部キーを作成することができます。 1対1の場合は - でリレーションシップを作成します。 もう一つ articles テーブルを作成して多対1のリレーションシップも作成してみます。 Enum articles_status_enum {   draft   published   private   deleted } Table articles {   id integer [pk]   title varchar   content text [note: 'Content of the article']   user_id integer   status articles_status_enum   created_at datetime [not null, default: `now()`]   updated_at datetime   Indexes {     user_id [name: "idx_articles_user_id"]   }   Note: 'table: articles' } Ref "fk_articles_user_id_users_id" : articles.user_id > users.id ここで articles テーブルの status カラムは Enum というユーザ指定の値を設定できるようにしています。 末尾の Ref の箇所で多対1のリレーションシップをarticles と usersで作成しています。 < : 1対多 ( 例: users. < articles.user_id ) > : 多対1 ( 例: articles.user_id > users.id ) - : 1対1 ( 例: users.id - profiles.user_id ) <> : 多対多 ( 例: shops.id <> products.id ) このようにDBMLからER図を生成することができます。 上記ではdbdiagram.io でプレビューしましたが、VsCode拡張機能の   DBML Live Preview  や  DBML Entity-Relationship Diagrams visualizer  を利用することでVsCode上でもプレビューすることができます。また、  vscode-dbml を利用することでSyntax HighlightingやSQLへの出力が可能になります。 SQLへの出力については npm パッケージ: @dbml/cli も利用できます。 Github actionsでCIを実行し、dbdocs.io で閲覧 ここからは Github Action を利用して、dbdocs.io 上でテーブル構造とER図を閲覧する方法を紹介します。 前提 まず、以下の前提のローカル環境を用意しdbdocs のアクセストークンを生成します。 node.js version: v20.12.2 npm version: 10.5.0 dbdocs のインストール & アクセストークン生成 以下のコマンドを実行し、dbdocs をインストールします。ここでのdbdocs のバージョンは 0.9.2です。 npm install dbdocs npx dbdocs login でログインし、dbdocs のアクセストークンを生成します。 npx dbdocs token -g ここで生成されたアクセストークンを Github actions のシークレット DBDOCS_TOKEN  として保存しておきます。 また、dbdiagram.io で作成していたDBMLをファイルとして保存しておきます。ここでは  ./project/blogsample.dbml に保存します。保存したファイルの最上部に以下のように記載して、dbdocs.io 上で閲覧できるように事前にプロジェクトの情報を記載しておきます。 Project BlogSample_MYSQL { database_type: 'MySQL' Note: ''' # BlogSample (MySQL) **References** : https://dbdocs.io/docs https://dbml.dbdiagram.io/home ''' } Github actionsのワークフロー記述 Github actionsのワークフローに以下のように記載します。ここでもう一つGithub actionsのシークレット  DBDOCS_PASSWORD_BLOGSAMPLE を設定し、dbdocs.io 上のドキュメントへのアクセスの際にパスワードをかけておきます。(パスワードを設定しないとパスワードなしで公開状態になります) name: CI on:   push:     branches: [ main ]   pull_request:     branches: [ main ] jobs:   build-with-dbdocs:     runs-on: ubuntu-22.04     steps:       - uses: actions/checkout@v4       - name: Install dbdocs         run: sudo npm install -g dbdocs       - name: Check dbdocs         run: dbdocs       - name: Update dbdocs project         env:           DBDOCS_TOKEN: ${{ secrets.DBDOCS_TOKEN }}         run: dbdocs build ./project/blogsample.dbml --password ${{ secrets.DBDOCS_PASSWORD_BLOGSAMPLE }} 有料版であれば招待された人のみが閲覧できるPrivateなプロジェクトが設定できます。詳しくは https://dbdocs.io/docs/project-access-control に記載されています。 テーブル構造のプレビュー Table Structure のタブでテーブル構造を確認することができます。 リレーションシップのプレビュー Relationshipsのタブでdbdiagram.io でプレビューしたようなER図を確認することができます。 まとめ DBMLファイルの作成・プレビュー、Github actions でCIを実行することでdbdocs.io でDBMLファイルのプレビューをすることができました。コードベースでDBのドキュメント管理が楽になりそうです。 参考URL https://github.com/holistics/dbml https://dbml.dbdiagram.io/docs https://dbdocs.io/docs https://dbdocs.io/docs/ci-integration https://dbdocs.io/docs/project-access-control ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DB設計書の管理が楽になるDBML入門 – DBMLの書き方,dbdiagram.io, dbdocs の紹介 – first appeared on SIOS Tech. Lab .
アバター
本ブログの対象読者 APIという言葉を何となく聞いたことがあるけど実装はしたことがない APIの理解に対して漠然とした不安を覚えている方 APIって最初の頃はなんかイメージがふわふわしてるよねって話 APIと聞くと皆さんはどんなことをイメージするでしょうか? まずAPIについてWikipediaで調べてみると “アプリケーションプログラミングインタフェース(API、英: application programming interface)とは、広義ではソフトウェアコンポーネント同士が互いに情報をやりとりするのに使用するインタフェースの仕様である。”「引用: Wikipedia 」 という感じで説明されています。 当然ですが、APIについてまだ学習したことのない方がこの説明をみても「???」ってなること間違いないと思います。 そこで今回はAPIを叩くという行為は実はインターネットで何か検索をしたことがある人は絶対にしたことがあるよということをお話した上でその仕組みについて解説いたします! ブラウザでURLを叩くということはつまり… みなさんはおそらく普段当然のように「スマートフォン、タブレット、パソコン」などでネット検索を行っていると思います。その際に使っているアプリケーションはおそらく「Google Chrome」や「Safari」と呼ばれるブラウザを利用しているのではないでしょうか? ここでは「パソコン」で「Google Chrome」を扱うと仮定して解説していきます。 初期ページの画面上部、もしくは画面真ん中上寄りに存在する検索バーで「りんご 品種 おすすめ」みたいな感じで普段検索を行っていると思います。 そして検索を行うと下記の画像のようなページに遷移すると思います。 このページでは「りんご 品種 おすすめ」の三単語で検索した結果、返ってきたWebページの一覧を表示してくれています。 では、一番上に出てきたWebページのリンクをクリックしてみます。すると該当のページが画面に表示されると思います。 ここまでで「検索結果一覧を表示した後にWebページのリンクをクリックする」という行いをしました。実は「Webページをクリックする」という行為そのものが「APIを叩く」という行為に深く関りがあります。 上記の画像で一番上のWebページのリンクが「 https://weathernews.jp/s/topics/201912/020175/ 」という感じになっています。実はWebページのリンクをクリックした際にこんな通信が行われていたということがブラウザの検証ツールで分かります。   ここで「リクエストメソッド」という欄に注目してください。こちらが「GET」になっています。 つまり、「ブラウザ上で検索結果のリンクを叩く」という行為は「topicAPIに対してGETメソッドでリクエストを投げている」ことと同じ意味になります。 皆様は知らず知らずのうちに「APIを叩く」という行為を実践していたことになりますね。 リクエストメソッドの種類 先ほど「リクエストメソッド」という単語が出てきたのでこちらを軽く説明していきます。 リクエストメソッドとはAPIを叩く際に指定する項目で大まかに分別すると「POST」、「GET」、「PUT」、「DELETE」の4種類があります。 それぞれ順番に「作成」、「取得」、「更新」、「削除」の意味合いがあります。 ブラウザでURLを叩くという行為は「ページを取得」するために行うので「GET」メソッドが該当しますね。 最後に 初めは誰でもAPIって聞くと「ナニソレオイシイノ」みたいな感じになってしまいがちです。。。 少しでも本ブログが「API理解」または「API恐怖症の克服」の助けになれば幸いです! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post APIって聞くと難しく考えちゃうけど、ブラウザでURLを叩く事とAPIを叩く事は同じ枠組みの話なんだよっていうお話 first appeared on SIOS Tech. Lab .
アバター
こんにちは、サイオステクノロジーの佐藤 陽です。 今回も ASP.NET Core についての記事を書いていきます。 今回は、第四弾として ASP.NET Core の DI コンテナの機能ついて解説していきたいと思います。 とは言いつつ、ASP.NET Core に依存した部分はそんなに大きくないので ASP.NET Core関係なしに DI って何? 依存性の注入って何? Injection の種類ってどんなのがあるの? といった方はぜひ最後まで読んでみてください! また繰り返しになりますが まだ自分も勉強中の身なので、記事の内容に誤りなどありましたらコメントにて指摘いただけると幸いです。 ではよろしくお願いいたします。 はじめに 今回は ASP.NET Core で提供される依存性注入(Dependency Injection = DI)および DI コンテナの機能について解説していきます。 優れたアーキテクチャを実装するうえでは欠かせない技術なので是非習得したいところです。 DI とは まずは DI について簡単に説明したいと思います。 DI は Dependency Injection の略で、日本語では 依存性の注入 と呼ばれます。 よく言われますが、この「依存性の注入」という日本語がなかなかクセが強くて分かりづらいですよね。 出来るだけ分かりやすく解説していきたいと思うので、ここでくじけず最後まで読んでいただけると幸いです。 Dependency まずは Dependency(依存性)の部分について解説します。 この「 依存性 」の重要さに関しては別の記事でまとめてありますので、こちらを読んでいたけると嬉しいです。 オブジェクト指向の強力な武器 ~依存関係の制御~ 簡単に述べると、ポイントとしては以下 2 点です。 依存先を安定した抽象(Interface)とする=依存関係逆転の原則 重要なビジネスルールが関係のない修正の影響を及ぼさないようにする=オープン・クローズドの原則 Injection 次に Injection(注入)の部分について解説します。 実はこれも 前回の記事の最後の方 に触れています。 IDataAccess dataAccess = new MySQLDataAccess(); ここの部分ですね。 Interface の変数を定義し、そこに実装されたクラスを new しています。 ただ 前回 の記事でも触れていますが、 このような形で単純に実装してしまうと依存関係が望ましくない形になってしまいます。 そこで 「このインスタンス化する処理をもっと外側に持っていき、依存関係に影響を与えないようにしよう」 というのが Dependency Injection の仕組みになります。 イメージ図ですが、以下のような感じです。 今回は先ほどのソースコードの例で、MySQLDataAccess を BusinessRule から利用したいとします。 この時、MySQLDatabaseAccessへの直接依存を避けるため以下2つの点に注意します。 BusinessRuleがIDatabaseAccess への依存するよう実装します。 MySQLDataAccess のインスタンス化も BusinessRule クラス内では行わない。 これを実現するため、どこか 外部のところでインスタンス化を行い、それを BusinessRule クラスに渡してあげる(=Injection) のです。 こうすることにより BusinessRule クラス自体は、MySQLDatabaseAccess クラスの存在を全く知らない(=依存しない)状態で、制御を行うことができます。 ではこのインスタンス化をはどこで行うのでしょうか? その解決方法が DI コンテナであり、次の章で詳しく見ていきたいと思います。 DI コンテナ DI コンテナとは上記したような DI の仕組みを実現するためのフレームワークです。 このフレームワークを使うことで、抽象(Interface)に対して、それを実装する具体的な型をマッピングすることができます。 ASP.NET Core では DI コンテナが標準搭載されており、今回はそれを使っていきます。 (標準以外の DI コンテナを ASP.NET Core 導入することも可能です) ASP.NET Core で提供される DI コンテナ DI コンテナを利用するにあたり、抽象型(Interface)と、具象型(実際に挿入するインスタンス)の依存関係を教えてあげる必要があります。 こうすることで、実際に使われるクラスでの挿入の部分や、インスタンスの作成および破棄の役割を DI コンテナが担ってくれます。 ASP.NET Core には①事前定義済みの抽象型と、②自分で登録できるカスタム定義の抽象型があります。 事前定義済みの依存関係 事前定義として用意されているものは多くあります。 参考: フレームワークが提供するサービス これらは明示的に DI コンテナに依存関係を登録しなくても利用することができます。 よく利用されるのは IWebHostEnvironment などでしょうか? この IWebHostEnvironment は実行環境の情報を持っており、開発環境・本番環境によって処理を切り分けることが可能となります。 せっかくなのでIWebHostEnvironment を試しに使ってみたいと思います。 今回はこれまでの記事でも出てきたサンプルの mvc プロジェクトをベースとし、IWebHostEnvironment を扱います。 実装の流れとしては BusinessRule クラス内で Injection された IWebHostEnvironment を利用して開発環境か本番環境か判定する関数(WebHostEnvironment)を実装する HomeController で 1.で実装されたメソッドを実行するような関数(Environment)を追加する といった形で実装したいと思います。 クラス構成としては以下のような形です。 作成・修正するファイルとしては以下4つです。 IBusinessRule.cs BusinessRule 用のインターフェイスの定義ファイル (あまりBusinessRuleのクラスっぽい事はしていませんが、そこは見逃していただけると…) BusinessRule.cs IBusinessRule を実装するクラスの定義ファイル HomeController.cs BusinessRule を呼び出すようなアクションを追加する Program.cs DI コンテナに対して、必要なサービスを注入する IBusinessRule.cs namespace aspnetcore_8_mvc {     public interface IBusinessRule     {         public string WebHostEnvironment();     } } BusinessRule.cs namespace aspnetcore_8_mvc {     public class BusinessRule : IBusinessRule     {         IWebHostEnvironment _env;         //DIコンテナからIWebHostEnvironmentをInjectionしている         //インスタンスの生成自体はこのクラス内で行わない         public BusinessRule(IWebHostEnvironment env)         {             _env = env;         }         public string WebHostEnvironment()         {             //Injectionされた値を利用して環境を判定             if (_env.IsDevelopment())             {                 return "開発環境です";             }             else             {                 return "本番環境です";             }         }     } } HomeController.cs using System.Diagnostics; using Microsoft.AspNetCore.Mvc; using aspnetcore_8_mvc.Models; namespace aspnetcore_8_mvc.Controllers; public class HomeController : Controller {     private readonly ILogger<HomeController> _logger;     private readonly IBusinessRule _businessRule;     public HomeController(ILogger<HomeController> logger, IBusinessRule businessRule)     {         _logger = logger;         _businessRule = businessRule;     }     //BusinessRuleを実行するためのActionを追加     public IActionResult Environment()     {         return Content(_businessRule.WebHostEnvironment());     }     public IActionResult Index()     {         return View();     }     public IActionResult Privacy()     {         return View();     }     [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]     public IActionResult Error()     {         return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });     } } Program.cs using aspnetcore_8_mvc; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.Configure<IISServerOptions>(options => {     options.AutomaticAuthentication = false; }); //DIコンテナにBusinessRuleをInjectionする builder.Services.AddSingleton<IBusinessRule, BusinessRule>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) {     app.UseExceptionHandler("/Home/Error");     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.     app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute(     name: "default",     pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); BusinessRule.cs 内で IWebHostEnvironment を利用して実行環境の判定を行っていますが、そのインスタンスはコンストラクタの引数として与えられています。 ではこの BusinessRule のコンストラクタの引数はどのように与えられているかというと、 アプリケーションのコードで明示的に与えるのではなく、DI コンテナの仕組みとしてインジェクションされているのです。 せっかくなので実行します。 https://localhost:44314/home/environment ちなみに補足ですが、「IWebHostEnvironment の型の引数をコンストラクタの引数に追加すればどこでも使える!」というわけではありません。 そのコンストラクタが定義されているクラスが DI コンテナに依存関係として登録されている必要があります。 今回であれば BusinessRule クラスですね。 ここは次に説明するカスタム依存関係の登録にも関わる部分なので、次章にて説明します。 カスタム定義の依存関係 事前定義済みの依存関係に関しては、特にアプリケーションコードでの準備は必要なく コンストラクタに引数を追加すればよいのですが、自分で定義した型を登録するためには明示的に追加してあげる必要があります。 このカスタム定義の依存関係なのですが、実は先ほどのサンプルコードにて IBusinessRule として既に実装済みです。 HomeController から BusinessRule クラスを利用していますが、 HomeController クラスにおいては BusinessRule クラスのインスタンスの生成は行っていません。 先ほどの IWebHostEnvironment と同様に、DI コンテナがインスタンス生成を行っています。 ただ、先ほどの事前定義のものとは違い、カスタム定義の依存関係を DI コンテナに事前に教えてあげる必要があります。 それが Program.cs に書かれている以下のコードです。 builder.Services.AddSingleton<IBusinessRule, BusinessRule>(); このようにインスタンス生成を DI コンテナに任せることで、 HomeController は BusinessRule クラスに依存していない という状況を実現できます。 これは 前回 の記事でも散々述べてきたことで、最重要ポイントでもあります。  実装の拡張 例えば、BusinessRule を異なるルールに置き換えたいとします。 あまりいい例ではないかもしれませんが、表示文字列を英語で返すような EnglishBusinessRuleクラスを定義します。 なお、実装する対象のインターフェイスは変わらず IBusinessRule です。 EnglishBusinessRule.cs namespace aspnetcore_8_mvc {     public class EnglishBusinessRule : IBusinessRule     {         IWebHostEnvironment _env;         public EnglishBusinessRule(IWebHostEnvironment env)         {             _env = env;         }         public string WebHostEnvironment()         {             if (_env.IsDevelopment())             {                 return "This is Development Environment";             }             else             {                 return "This is Production Environment";             }         }     } } クラスの関係性としては以下のような形です。 では、BusinessRule クラスから EnglishBusinessRule クラスに置き換えをしたい場合、どういった修正が必要になるでしょうか? 今回は、DIコンテナを利用しているため、 Program.cs において依存関係を登録している部分のみの修正で実現できます。 //builder.Services.AddSingleton<IBusinessRule, BusinessRule>(); //↓ builder.Services.AddSingleton<IBusinessRule, EnglishBusinessRule>(); 実行してみます。 https://localhost:44314/home/environment メッセージが英語で表示されていることが確認できました。 仮に DI コンテナを利用していない場合、BusinessRule クラスのインスタンスを生成しているすべての箇所のソースコードの修正が必要になります。 その点、DI コンテナを利用することで 呼び出し側の修正なしで変更できるので、変更量が少なくて済みます。 ライフタイムの管理 DI コンテナに依存関係を伝える手段として、ASP.NET Core には 3 種類の方法が提供されています。 AddTransient 呼び出しのたびに指定した型の新しいインスタンスが呼び出し元に返される AddSingleton 指定した型の最初に作成されたインスタンスが呼び出し元に返される 型に関係なく、各アプリケーションが独自のインスタンスを取得する  AddScoped AddSingletonと同じだが、スコープは現在のリクエストになる    (出典: プログラミングASP.NET Core ) どれを使うかはアプリケーションの設計に基づいて決定します。 例えばRESTfulなAPIを実装する場合を想定すると、 前の状態に依存したりしないのでAddSingletonで追加しても動作に影響なく、かつ無駄なインスタンス生成が行われないので良さそうな選択です。。 また 書籍 に以下のような注意事項が書かれていました。 この時注意することとして、特定のライフタイムで登録されたコンポーネントが、それよりも短いライフタイムで登録された他のコンポーネントに依存できないことです。 確かにSingletonとして登録されたコンポーネントAに対して、Transientとして登録されたコンポーネントBを注入した場合、コンポーネントBが想定されたライフタイムよりも長生きしてしまう可能性があります。 必ずしもバグが発生するとは限りませんが、なんだか良からぬ事が発生してしまいそうです。 この点注意してライフタイムの管理をしていきましょう。 まとめ 今回はASP.NET CoreのDIコンテナについての概要を解説しました。 このDIコンテナを正しく扱うことで、以前書いた 「依存性の制御」 をより強力に扱うことができるようになります。 DIコンテナもまだまだ奥が深い部分がありますが、このあたりがしっかり理解できると、DDDやClean Architectureといったようなアーキテクチャもうまく扱えるようになると思います! 今回の記事で「何となく分かったなぁ」となった方は、また色々と深堀してみてください! ではまた! 参考文献 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ASP.NET Core入門 – DIコンテナ 解説【.NET 8】 first appeared on SIOS Tech. Lab .
アバター
こんにちは。サイオステクノロジーの橋本です。 今回は DISK (ボリューム) 管理方法の違いによる性能差を見ていきたいと思います。 よくこういう意見耳にしませんか?  LVM はオーバヘッドがあるから遅い  NFS は非常に遅いのでバックアップ用に適している  物理ボリュームに直接ファイルシステムを作成する方法が一番無難 (そして DISK 拡張できず運用になやむ) 実際にどれくらいの性能差があるのか以下の 4 パターンで検証してみます。 検証パターン 1: 物理ボリュームに直接ファイルシステム (以下、「直 xfs」と呼称)  50 GB の DISK 1 本をサーバにアタッチ  LVM など用いずに DISK 上に直接ファイルシステム (xfs) を作成 2: 物理ボリューム 1 本で 1 つのボリュームグループ作成 (以下、「LVM ×1」と呼称)  50 GB の DISK 1 本をサーバにアタッチ  LVM を用いて対象の DISK 論理的に管理しファイルシステム (xfs) を作成 3: 物理ボリューム 25 本で 1 つのボリュームグループ作成 (以下、「LVM ×25」と呼称)  2 GB の DISK を 25 本用意し、すべてをサーバにアタッチ  LVM を用いて 25 本の DISK を 1 つのボリュームグループとして束ね、ファイルシステム (xfs) を作成 4: NFS  文字通り NFS (Network File System)   DISK 管理方法と異なるレイヤーですが、NFS 上に PostgreSQL のデータを格納し検証してみます。 なお、NFS サーバは同一 AZ 内に別サーバとして用意しました。 ※raw デバイスは RHEL 9 から利用できなくなったので  今回は検証しません(できません) 前提 主要なパッケージやOSのバージョン OS バージョン Red Hat Enterprise Linux release 9.4 Kernel kernel-5.14.0-427.13.1.el9_4.x86_64 PostgreSQL postgresql16-16.2-1PGDG.rhel9.x86_64 LVM lvm2-2.03.23-2.el9.x86_64 nfs nfs-utils-2.5.4-25.el9.x86_64 サーバのリソース CPU 2コア メモリ 8GB DISK OS 領域 15GB 検証用 (DB) 領域 50GB   OS 領域はいずれの検証パターンでも LVM を用いず DISK 上に直接ファイルシステム (XFS) を作成したものを利用 DISK サイズはすべての検証パターンで 50 GB になるように調整しサーバにマウントしました。 マウントした 50 GB を PostgreSQL のデータ領域 ($PGDATA) として利用します。 当然いずれの検証パターンにおいても DISK そのものの性能差はありません。 検証方法 検証はすべて pgbench を用います。 以下のコマンドを用いて検証用のデータを作成しました。 pgbench -i -s 2500 TESTDB 以下のように負荷を掛けることで DISK 性能を計測します。 # pgbench -c 200 -t 100 TESTDB pgbench (16.2) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 2500 query mode: simple number of clients: 200 number of threads: 1 maximum number of tries: 1 number of transactions per client: 100 number of transactions actually processed: 20000/20000 number of failed transactions: 0 (0.000%) latency average = 182.821 ms initial connection time = 754.209 ms tps = 1093.966050 (without initial connection time) # 噛み砕いていうと同時に 200 クライアントが DB に接続を行い、 それぞれのクライアントが 100 トランザクションを実行します。 今回、以下の 2 点の結果を見ます。 ・latency average  1トランザクションの実行時間 (単位は ms)  数値が短い程高速に完了していることを示します。 ・tps = xxxxxx (without initial connection time)  1 秒あたりの実行トランザクション数 (接続確立に要した時間を考慮せず)  数値が大きい程大量のトランザクションを処理していることを示します。 なお、検証はブレを考慮してそれぞれのパターンで 10 回行います (計40回検証)。 検証結果 : latency average 検証 10回のサマリ 平均値 最小値 最大値 直 xfs 185.8769 ms 181.374 ms 189.893 ms LVM ×1 185.5508 ms 180.168 ms 198.081 ms LVM ×25 188.4649 ms 182.428 ms 197.622 ms nfs 243.9293 ms 227.067 ms 254.882 ms 個別の結果 (単位はすべて ms) 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 直 xfs 182.821 185.401 181.519 188.62 185.515 189.893 181.374 189.672 184.623 189.331 LVM ×1 180.691 180.168 182.824 192.308 181.503 198.081 183.759 191.254 182.587 182.333 LVM ×25 182.428 186.594 185.742 192.513 187.926 197.622 185.209 187.631 186.238 192.746 nfs 227.067 229.767 248.523 254.183 244.819 247.029 254.882 236.622 254.582 241.819 検証結果 : tps 検証 10回のサマリ 平均値 最小値 最大値 直 xfs 1076.294 1053.222 1102.692 LVM ×1 1078.886 1009.69 1110.075 LVM ×25 1061.742 1012.033 1096.325 nfs 821.1957 784.6754 880.7962 個別の結果 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 直 xfs 1093.966 1078.742 1101.81 1060.335 1078.079 1053.222 1102.692 1054.451 1083.29 1056.351 LVM ×1 1106.864 1110.075 1093.947 1039.999 1101.913 1009.69 1088.381 1045.73 1095.371 1096.891 LVM ×25 1096.325 1071.844 1076.765 1038.889 1064.246 1012.033 1079.861 1065.923 1073.894 1037.636 nfs 880.7962 870.4461 804.7554 786.8345 816.9299 809.6224 784.6754 845.2306 785.601 827.0654 所感 所感としては「直 xfs」と「LVM ×1」の差はほぼ無いと言えます。 平均値として 0.3 ms の差なので誤差の範疇だと推測します。 ※ 0.3 ms の差が致命的になるシステムも金融、証券系などで存在するため  そういう場合はより厳密な検証が必要です しかしながら、LVM で束ねている物理 DISK の数が多くなると、 3 ms と有意な差が現れ始めました。 おそらくですが物理 DISK が多くなるとこの差はより広がると推測されます。 「気にする程度か?」という気もしますが、 ここら辺になるとチリも積もればで影響が出るシステムもあるかもしれません。 nfs は DB として利用できないくらい遅い、、、と検証前思っていましたが 大分健闘した数値となりました。 ※同一 AZ 内だったのでこれくらいの数値に収まったと推測します。 ちなみに伝わる人には伝わると思いますが、 格闘ゲームでよく言われる「フレーム」ですが 1 フレームは約 16ms です。 また、人間の反応速度の限界は(諸説ありますが) 200 ms 前後といわれます。 一般的なモニターの応答速度で5 ms前後です。 個人的な主観で言いますと、 LVM を用いた時に生じた数 ms の差は人間が知覚できない範囲の話であり、 シビアなシステムでない限り LVM の利便性を捨てる理由にはならないと考えます。 最後に 本検証はあくまで参考としていただければ幸いです。 より厳密な検証を行うには数百~数千回の検証を行い誤差をなくし精度を上げる必要があります。 また、今回は PostgreSQL で検証を行いましたが、システムや検証方法によっては 異なる結果が出る場合もあるかもしれません。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DISK 管理の性能差を検証してみよう ~直接xfs、LVM、nfsの性能差~ first appeared on SIOS Tech. Lab .
アバター
PS/SLの佐々木です。 今回はSBOMツールのScanCode.ioの調査記事になります。 SBOMとはなんぞやという方はまずは こちら から読んでみてください。 ScanCode.ioとは ScanCode.ioとはソフトウエア構成解析を自動化し、アプリケーションのOSSコンポーネントとそのライセンスを解析します。 ScanCode.ioを使用するメリットは以下の二つです。 サードパーティーのライブラリを使用する前にライセンスを知る必要がある 古かったり脆弱性があるコンポーネントの使用を避ける ScanCode.ioで解析をするためには4つの方法が紹介されています。 ユーザーインタフェース ScanCode.ioのUIは、ソフトウェア構成物のスキャンや結果の表示、設定の変更などの操作をユーザーが行うためのグラフィカルなインターフェースを提供します。 REST API 外部アプリケーションやサービスがScanCode.ioの機能を利用できるようにするためのプログラムインターフェースです。これにより、外部のツールやシステムがScanCode.ioを自動化したり統合したりすることが可能になります。 コマンドラインインタフェース ターミナルやシェルでScanCode.ioのコマンドを実行して、ソフトウェア構成物のスキャンや結果の表示、設定の変更などを行うことができます。 データモデル ソフトウェア構成物やそのコンポーネント、ライセンス情報などのデータの構造と関係を定義します。これにより、ScanCode.ioがソフトウェアの構成情報を収集し、効果的に管理できるようになります。 実際に使用してみる ユーザーインタフェース git clone <https://github.com/nexB/scancode.io.git> && cd scancode.io make envfile docker compose build docker compose up -d localhostにアクセスするとブラウザで開くことができる Docker imageを解析してみる 今回解析するDocker Imageは apline/httpe です。 下記画像のように入力を行いCreateボタンを押下するとソースコードの解析結果が得られます。 解析できるパイプラインの項目には以下のようなものがあります。 関数 説明 analyze_docker_image Dockerイメージを解析します。 analyze_root_filesystem_or_vm_image LinuxのルートファイルシステムまたはVMイメージを解析します。 analyze_windows_docker_image WindowsのDockerイメージを解析します。 inspect_packages アプリケーションパッケージのアーカイブ/コードベースを検査し、オプションで事前解決された依存関係が含まれています。パッケージのマニフェストと依存関係に存在するパッケージを検査します。 load_inventory ScanCode-toolkitのスキャン結果やScanCode.ioのスキャン結果を処理します。 load_sbom SPDX/CycloneDX SBOMまたはABOUTファイルをプロジェクトにインポートします。 map_deploy_to_develop 開発とデプロイメントの両方のコードベースが関係する場合に使用します。 resolve_dependencies コードベースにロックファイルや他のパッケージマニフェストがある場合、パッケージ要件からパッケージを解決します。 scan_codebase コードをアーカイブとして圧縮し、各ファイルにリンクされているすべての既存パッケージを検出します。オプションで事前解決された依存関係も含めることができます。 scan_single_package 単一のパッケージアーカイブがある場合に使用し、そのライセンス、著作権、パッケージのメタデータに関する情報を取得します。 以下は解析した結果になります。 様々な解析結果を眺めることができます。 タイプとライセンスでのフィルタリングの結果を円グラフの形式で表示します。 プログラミング言語 、 MIME タイプ 、 所有者 、 著作権 、  ライセンス キー 、および ライセンス カテゴリ によってコード リソースをフィルタリングする円グラフのグループが提供されます。 解析された項目をクリックすると下記のような解析項目に入っているパッケージの一覧が表示されます。 脆弱性の解析 今回の解析結果に脆弱性が含まれているかどうか確認したい場合があると思います。 ScanCode.ioではVulnerableCodeと統合して脆弱性がないか判断することができます。 ローカルに組み込むには .env ファイルに以下を追加してください。 VULNERABLECODE_URL=https://public.vulnerablecode.io/ 追加後はサービスを再起動します。 docker compose restart web worker 再起動後Webに戻りプロジェクトページのAdd piplineボタンを押下します。 モーダルが表示されたら find_vulnerabilities を選択しAdd piplineを押下します。 パイプラインの実行が終わり脆弱性が見つかるとPackageのところに赤い虫マークのようなものがあり、これがあると脆弱性が見つかったことになります。 虫マークをクリックすると脆弱性の詳細を見ることができます。 https://public.vulnerablecode.io/vulnerabilities/VCID-wavq-xut5-aaak 上記URLのような脆弱性が確認されていることがわかります。 今回はWebUIでの解析方法を紹介しましたが、コマンドラインやREST, APIでも同様のことができます。 またスキャンを自動化し、定期的に実行したりソースコードのコミットやリリースに応じて実行するようにスケジュールすることができます。(この記事ではやりませんが興味のある方は以下のドキュメントを確認してみてください。) https://scancodeio.readthedocs.io/en/latest/automation.html Dependency-TrackでSBOMを読み込んでみる 最後に以前紹介したDependency-Trackを使用してSBOMを読み込んでみたいと思います。 Dependency-Trackについて知りたい方は こちら を参照してみてください。 ScanCode.ioからCyclone DXのSBOMをExportしてDependency-Trackにimportしてみました。(Download results as:のCycloneDXという項目押下するとダウンロードされます。) 問題なく取り込まれたことが確認できました。 結果を確認するとrisk scoreが高いものが5件3件あることがわかりますね。 確認してみます。 一つ目のものはScanCode.ioのほうでも脆弱性リスクがあると警告が出ていたものと同様です。 Dependency-Trackは様々な脆弱性報告サイトと連携することができるので幅広い情報ソースから脆弱性を検出することができます。 他二つはScanCode.ioでは検出されていなかったものになります。 pip関連の脆弱性のようです。 終わりに 今回はScanCode.ioのWebUIに関する調査検証を行っていきました。 ScanCode.ioは様々な形式のソースコードを解析することができるのが非常に強みで、CI/CDに組み込んで解析を自動化したりすることも可能そう(ちょっとここはドキュメント読んだだけなので確証はないですが。。。)でした。 一方で脆弱性検出のソースが一つしか紹介されていなかったり、少々解析結果の詳細が見にくかったり、通知機能がなかったりしました。 その点は以前紹介したDependency-Trackが優れいているので併用して使うことで非常に解析の体験が向上するのではないかと思いました。 参考 ScanCode.io公式ドキュメント VulnerableCode公式ドキュメント Dependency-Trackについて ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ScanCode.ioの調査 first appeared on SIOS Tech. Lab .
アバター
はじめに こんにちは!PS SLのなーがです。前回は「SBOMツール紹介 ~ bom: The SBOM Multitool編 ~」について書きましたが、今回はBOMツールの一つである「CycloneDX Generator」を使ってSBOMを作成する方法について解説します。SBOMについてよく分からないという方は、まず こちら の記事を読んでみてください。 CycloneDX Generatorとは ほとんどのSBOMツールは単純なバーコードスキャナのようなもので、簡単なアプリケーションの場合深く検査することなくコンポーネントのリストだけを作成する 言語またはパッケージマニフェストごとにSBOMを生成する従来の技術は、エンタープライズ環境では機能しないか、コンプライアンスと自動解析の両方に必要な信頼性が低い CycloneDX Generatorはユーザーフレンドリーで正確かつ様々な多くの言語とパッケージマネージャーをサポートしたCycloneDX形式の部品表(BOM)を作成するCLIツール、ライブラリ、REPL、およびサーバーとして開発された 環境 OS、ツール バージョン Ubuntu 22.4 cdxgen 10.3.5 サポートされている言語とパッケージ形式 言語/プラットフォーム パッケージ形式 推移的な依存関係 証拠 Node.js npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js .min.jsを除く Yes Java maven (pom.xml [1]), gradle (build.gradle, .kts), scala (sbt), bazel Maven が利用できないかエラーのために pom.xml が手動で解析される場合を除く Yes Android apk, aab PHP composer.lock Yes Yes Python pyproject.toml, setup.py, requirements.txt [2], Pipfile.lock, poetry.lock, pdm.lock, bdist_wheel, .whl, .egg-info 自動でpip install/freezeします。無効化されれている場合はPipfile.lockとpoetry.lockのみ Yes Go binary, go.mod, go.sum, Gopkg.lock binaryを除く Yes Ruby Gemfile.lock, gemspec Gemfile.lockのみ Rust binary, Cargo.toml, Cargo.lock Cargo.lockのみ .Net .csproj, .vbproj, .fsproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock, binary project.assets.json,、packages.lock.json,、paket.lockのみ Dart pubspec.lock, pubspec.yaml pubspec.lockのみ Haskell cabal.project.freeze Yes Elixir mix.lock Yes C/C++/Objective C/C++11 conan.lock, conanfile.txt, *.cmake, CMakeLists.txt, meson.build, codebase without package managers! conan.lockのみ。バージョン番号なしのcmakeのベストエフォートベース。 Yes Clojure Clojure CLI (deps.edn), Leiningen (project.clj) clojure cli または leiningen コマンドがないためにファイルが手動で解析される場合を除く Swift Package.resolved, Package.swift (swiftpm) Yes Docker / oci image サポートされているすべての言語。プラグインを含む Linux OS パッケージ [4] ロックファイルに基づくベストエフォート型 Yes GitHub Actions .github/workflows/*.yml N/A Yes Linux サポートされているすべての言語。プラグインを含む Linux OS パッケージ [5] ロックファイルに基づくベストエフォート型 Yes Windows All supported languages. OS packages with best effort [5] ロックファイルに基づくベストエフォート型 Yes Jenkins Plugins .hpi files Yes Helm Charts .yaml N/A Skaffold .yaml N/A kustomization .yaml N/A Tekton tasks .yaml N/A Kubernetes .yaml N/A Maven Cache $HOME/.m2/repository/**/*.jar N/A SBT Cache $HOME/.ivy2/cache/**/*.jar N/A Gradle Cache $HOME/caches/modules-2/files-2.1/**/*.jar N/A Helm Index $HOME/.cache/helm/repository/**/*.yaml N/A Docker compose docker-compose*.yml. イメージもスキャンされます。 N/A Dockerfile Dockerfile  イメージもスキャンされます。 N/A Containerfile Containerfile . イメージもスキャンされます。 N/A Bitbucket Pipelines bitbucket-pipelines.yml イメージとpipesもスキャンされます。 N/A Google CloudBuild configuration cloudbuild.yaml N/A OpenAPI openapi*.json, openapi*.yaml N/A 脚注: [1] – マルチモジュール アプリケーションの場合、BOM ファイルには、パッケージ化された war ファイルまたは Ear ファイルに含まれていないコンポーネントが含まれる可能性があります。 [2] – 精度を向上させるためにピップフリーズが自動的に実行されます。仮想環境が必要です。 [3] – dotnet または nuget の復元を実行して project.assets.json を生成します。このファイルがないと、cdxgen には間接的な依存関係が含まれません。 [4] – プラグインに関するセクションを参照 [5] – osquery を利用しています。プラグインのセクションを参照してください 走査対象 JavaでWebアプリケーションを作成する際に使用される Tomcat を対象とします。 セットアップ コンテナイメージを使用 SBOMを作成したいディレクトリでコンテナイメージを実行します。 docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen -r /app -o /app/bom.json { "bomFormat": "CycloneDX", "specVersion": "1.5", "serialNumber": "urn:uuid:78c22561-855e-4816-94e4-a0f8cfda4876", "version": 1, "metadata": { "timestamp": "2024-04-11T09:29:16.559Z", "tools": [ { "vendor": "cyclonedx", "name": "cdxgen", "version": "10.3.5" } ], "authors": [ { "name": "OWASP Foundation" } ], "component": { "group": "org.apache.tomcat", } ... } } インストール npm install -g @cyclonedx/cdxgen   Homebrew を使用している場合は、下記のコマンドでインストールできます。 brew install cdxgen バージョンを確認します。 cdxgen -v インストールされていることが確認できました。 SBOM作成 実際にSBOMを作成します。デフォルトでは「bom.json」として生成されます。 cdxgen 上記のコマンドでもSBOMを生成出来ますが、 Tomcat はJavaのプロジェクトなのでオプションで指定します。この場合、Maven、Gradle、または sbt を自動的に検出し、それに応じて bom をビルドしてくれるようです。また、出力ファイル名も指定します。 cdxgen -t java -o bom-tomcat.json { "bomFormat": "CycloneDX", "specVersion": "1.4", "serialNumber": "urn:uuid:718baa3f-3d7c-4f12-be31-8609c4c80bed", "version": 1, "metadata": { "timestamp": "2024-04-12T02:56:34.800Z", "tools": [ { "vendor": "cyclonedx", "name": "cdxgen", "version": "10.3.5" } ], "authors": [ { "name": "OWASP Foundation" } ], "component": { "group": "org.apache.tomcat", } ... } } 仕様バージョンの指定したい場合は、引数「–spec-version」を使用してバージョン番号を渡します。現バージョンのcdxgenで使用されるデフォルトの仕様は 1.5なので、ここではバージョン1.4を指定します。 cdxgen -o bom-1_4.json --spec-version 1.4 { "bomFormat": "CycloneDX", "specVersion": "1.4", "serialNumber": "urn:uuid:0398f42d-760c-4d60-b443-62fff1e0571c", "version": 1, "metadata": { "timestamp": "2024-04-12T05:06:15.027Z", "tools": [ { "vendor": "cyclonedx", "name": "cdxgen", "version": "10.3.5" } ], "authors": [ { "name": "OWASP Foundation" } ], "component": { "group": "org.apache.tomcat", } ... } } その他のオプションについては、 こちら を参照してください。 また、C または Python 用の SBOM を生成するには、Java >= 21 が必要なので、インストールしてから実行してください。 SBOMサーバー 引数「–server」を使用することで、サーバーモードで実行できます。デフォルトでは9090をListenしていますが、引数「–server-port」でポートを指定できます。 cdxgen --server --server-port 8888 コンテナイメージでは、以下のように指定します。 docker run --rm -v /tmp:/tmp -p 9090:9090 -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen -r /app --server --server-host 0.0.0.0 その他のオプションについては、 こちら を参照してください。 また、サーバーへのアクセスはCurlコマンドまたは Postman 等のツールを使用してアクセスします。 稼働状況の確認 health エンドポイントを使用して、SBOM サーバーが稼働しているかどうかを確認します。 curl "http://127.0.0.1:8888/health" ローカルリポジトリのスキャン sbomエンドポイントにクエリパラメータでローカルリポジトリへの絶対パスを指定します。 curl "http://127.0.0.1:8888/sbom?path=XXXXX/tomcat&type=java" Gitリポジトリのスキャン sbomエンドポイントにクエリパラメータでリモートリポジトリへのパスとtypeを指定します。 curl "http://127.0.0.1:8888/sbom?url=https://github.com/apache/tomcat.git&type=java" 認証情報が必要な場合は、下記のように指定します。 curl "http://127.0.0.1:8888/sbom?url=https://<access_token>@github.com/XXXXX/YYYYY.git&..." curl "http://127.0.0.1:8888/sbom?url=https://<username>:<password>@bitbucket.org/XXXXX/YYYYY.git&..." また、引数を指定することで、POSTによるスキャンを行うこともできます。 curl -H "Content-Type: application/json" http://localhost:8888/sbom -XPOST -d $'{"url": "https://github.com/apache/tomcat.git", "type": "java"}' Docker リポジトリをCloneしてDockerによる実行もできます。 git clone https://github.com/CycloneDX/cdxgen.git docker compose up sbomエンドポイントにクエリパラメータでリモートリポジトリへのパスとtypeを指定して、SBOMを作成してみます。 その他 このツールはSBOM以外のCycloneDX形式のBOMを出力する機能がありますが、今回はSBOMを作成することが目的なので、他BOMの作成については省略します。興味のある方は こちら を参考にして作成してみてください。 さいごに 今回はSBOMツールの一つである「CycloneDX Generator」について解説しました。前回の調査した「bom: The SBOM Multitool」はまだ開発途中で機能も少なかったですが、今回のツールはCycloneDX コミュニティが作成しているだけあって多くの機能を備えているかつ活発に開発・リリースが行われていました。これからも様々なSBOMツールの使い方について投稿していこうと思います! 関連記事 SBOM解説: SBOMのメリットと導入の流れ SBOMツールをカテゴリー分けしてみた SBOMの仕様:CycloneDX(CDX)・SPDX SBOMツール紹介 ~ Dependency-Track編 ~ SBOMツール紹介 ~ bom: The SBOM Multitool編 ~ SBOMツール紹介 ~ FOSSology編 ~ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SBOMツール紹介 ~ CycloneDX Generator編 ~ first appeared on SIOS Tech. Lab .
アバター
こんにちは。サイオステクノロジーの塙です。 今回はKubernetes をベースとしたプラットフォームでGPUを扱っていくための手法について解説してみます。 概要 直近では特にAIや機械学習(ML)に関する話題が増え、これらの分野を活用したソリューションの実現を図る組織も多いのではないでしょうか。 これらの分野の計算リソースのためには、GPUが必要となってきます。 そして、GPUリソースを効率的に使用するために、Kubernetes と組み合わせてGPUを管理し、コストの削減と効率化が期待出来ます。 コンテナ環境を利用することで、機械学習(ML)のための複雑な環境を何度も同じようにセットアップすることができる kubernets のスケジューリングにより、リソースの利用率の効率化をすることができる では、KubernetesでGPUを扱うためにはどんな準備が必要となるのかを説明していきます。 KubernetesでのGPUの使用 Kubernetes でのGPUスケジューリング*1 を有効にするためには、デバイスプラグインを使用します。 デバイスプラグインは、特定のハードウェアのリソースを管理するためのgRPCサービスとなります。Kubelet がデバイスプラグインと連携することでGPUをコンテナに割り当てることが可能になります。 デバイスプラグインについての詳細は以下をご参考下さい。 参考 Device Plugins   *1 GPU スケジューリング: 複数のプロセスが同時に実行されるGPUのリソースを効率的に管理するためのプロセスです。 これは、タスクの優先順位付けや、タスクのリソース割り当てなどを行い、GPUリソースの使用率を高め全体的なパフォーマンスを向上させることに繋がります。 GPUスケジューリングは、特に並列計算が求められるAIや機械学習(ML)向けアプリケーションで重要な機能となっている。   具体的にKubernetesでGPUを使用するために以下の対応が必要です。(ここでは、NVIDIAを例にしてます) 対応するベンダーのGPUドライバーをノードにインストールする 前提として、gcc と 正しいカーネルバージョンのインストールが必要です 詳細は、 NVIDIA CUDA Installation Guide for Linux を参照 Kubernetes でデバイスプラグインをインストールする Kubernetes からyamlファイルでデプロイします 詳細は、 https://github.com/NVIDIA/k8s-device-plugin?tab=readme-ov-file#example-for-debian-based-systems- with-docker-and-containerd  を参照   ■ Kubernetes のオブジェクトからの使用方法 デバイスプラグインまでインストールを行った後、従来のCPU/メモリをリクエストするのと同様に、カスタムGPUリソースをリクエストすることで、Pod から GPUを使用することが可能になります。 apiVersion: v1 kind: Pod metadata: name: test-gpu-pod spec: restartPolicy: OnFailure containers: - name: test-gpu-container image: registry.example/example/example:v10.2 resources: limits: nvidia.com/gpu: 1 # requesting 1 GPU   Kubernetesでのデバイスプラグインの制限について Kubernetes の Schedule GPUs  、 Device Plugins を参照すると、以下のような制限が記載されています。 コンテナ間でGPUを共有することは出来ない 拡張リソースはオーバーコミットすることは出来ない マニフェスト定義でresources.limits を指定する形式である resources.request を指定する時は、resources.limits と同じにする必要がある   GPUリソースを指定する時には上記の制限に注意したいところですが、特に気になったものは コンテナ間でGPUを共有することは出来ない という制限です。 Kubernetes上のコンテナとして扱うからには、AIや機械学習(ML)向けアプリケーションのワークロードを分割して実行したいと思います。ただし、この制限があるとその分GPUを搭載する必要が出てきてしまいます。 単体だけでもコストのかかるGPUを、コンテナ数分用意するとなると非常に高価になってしまいます。 そのため、NVIDIAや他のベンダーが、Kubernetesのコードをベースとしたソリューションを実装して、GPUリソースの共有を提供できる形にしています。 GPUへの共有アクセス NVIDIA のデバイスプラグインを例に、GPUへの共有アクセスを提供している機能を記載します。 下記、Time-Slicing と MPS は相互に排他的となります。   ■ Time-Slicing タイムスライシングスケジューラを活用して、複数のCUDAプロセスを同時に実行します。 GPUは一定間隔でCUDAプロセスを切り替えることによって複数プロセスの共有が可能となります。 GPUのレプリカセットを定義することができ、各レプリカをPodにリソースとして提供することが出来ます。 version: v1 sharing: timeSlicing: resources: - name: nvidia.com/gpu replicas: 4 # 単一のGPUを4つのレプリカとして提供する 設定した後は、GPUリソースに.sharedが付与されるので、それをGPUリソースとして利用します。 apiVersion: v1 kind: Pod metadata: name: test-gpu-pod spec: restartPolicy: OnFailure containers: - name: test-gpu-container image: registry.example/example/example:v10.2 resources: limits: nvidia.com/gpu.shared: 1 # requesting 1 GPU 注意点としては以下があります。 複数のGPUをリクエストしても、比例して計算能力が向上することが保証されない プロセス間の切り替え時にオーバーヘッドが発生する メモリ制限は考慮されていない。1つのプロセスが異常終了すると、他のプロセスも影響して終了する GPUを共有して使用しているため   ■ MPS (Multi Process Service) こちらも、複数のCUDAプロセスが単一のGPUを共有出来るようにする機能です。制御を行うdaemon を使用して、アクセスを管理します。 Time-Slicing のデメリットであるオーバーヘッドを排除しています。 各プロセスに独自のメモリアドレス空間を提供することにより、プロセスにメモリの制限を適用することが出来ます。   注意点としては以下があります。 プロセスを完全分離させているわけではないため、メモリの保護の提供はされていない あるプロセスが異常終了した場合に、他のプロセスに影響を与える可能性があります 参考  https://docs.nvidia.com/deploy/mps/index.html   ■ MIG (Multi Instance GPU) 単一の物理的なGPUを複数の独立したGPUインスタンスに分割することが出来る機能です。 利用可能なGPUとしては、 Ampere , Hpper  などがあります。   注意点としては以下があります。 各GPUのモデルによって、特定のMIGプロファイルをサポートするため、柔軟なカスタムを行うことは出来ない 参考  Supported MIG Profiles まとめ 今回は、Kubernetes でGPUを扱っていくための手法についてまとめてみました。 今やクラウドベースでGPU搭載のインスタンスを使用してKubernetes を構築出来るようですが、その前提となっている技術等について改めて簡単に整理してみると面白いです。 次回は、実際の構築例を試してみて所感を記載していこうと思います。 本書の記載が読者のお役に立てれば幸いです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post KubernetesでGPUを使用する first appeared on SIOS Tech. Lab .
アバター
こんにちは、サイオステクノロジーの佐藤 陽です。 今回はオブジェクト指向プログラミングの強力な武器の一つである、 ポリモーフィズムを利用した依存関係の制御 について書きたいと思います。 「依存関係性の制御」や、「依存関係性の逆転(DIP)」などは既に色々なところで解説されていますが 自分の知識定着と、どこかの誰かの役に立つことを期待して書いていきたいと思います。 良ければ最後までご覧ください! はじめに 先日、今更ながら「 Clean Architecture 達人に学ぶソフトウェアの構造と設計 」を読んだのですが その中で個人的に刺さる一文がありました。 それが以下のものです。 OO とは「ポリモーフィズムを使用することで、システムにあるすべてのソースコードの依存関係を絶対的に成業する能力」である。 ※OO=オブジェクト指向 この一文に感銘を受け、この気持ちをアウトプットせざるを得なかったため、今回の記事を書くに至っています。 オブジェクト指向プログラミングのメリット よくオブジェクト指向のプログラミングのメリットとして 現実世界に近い形でプログラミングが可能 カプセル化 継承 といったものが挙げられますが、Clean Architectureの書籍の中では 「これらはオブジェクト指向の大きなメリットではない」とバッサリと切り捨てられていました。 (本記事ではこの点には触れないため、気になる方はぜひ 4 章「オブジェクト指向プログラミング」を読んでみてください。) ではオブジェクト指向の一番の強みとは何かというと、先ほども書いた 「ポリモーフィズムを利用した依存関係の制御」 と述べています。 この点に関して自分なりに整理していきたいと思います。 ポリモーフィズムとは はじめにポリモーフィズムについて簡単に説明します。 こちらも色々なところで記事にされているので、ここではサクっとだけ。 ポリモーフィズムは「同じ関数であっても、別の動作をするような処理」を実現します。 よく挙げられる例として動物の鳴き声があります。 「鳴く」という動作注目した場合 犬であれば「ワンワン!」、猫であれば「にゃー!」、馬であれば「ヒヒーン!」と鳴きます。 「同じ動物」の同じ「鳴く」という動作であっても、発せられる声は異なってきます。 これを実現するのがポリモーフィズムです。 今回はこれを以下のような形で実施します。 動物( IAnimal )というインターフェイスを定義し、鳴く( MakeSound )というメソッドを定義します。 そしてこの Interface を実装するDog、Cat、Horseのクラスを実装します。 そして、この Interface のインスタンスとして生成した変数( animal )から MakeSound() を呼び出すと 変数として代入した動物の鳴き声が生成されます。 今回、 animal 変数の生成を自前で書いているのであまり恩恵を感じられていませんが DI コンテナなどの組み合わせることによってポリモーフィズムは非常に強力な真価を発揮します。 現時点では、「同じ関数でも動作を切り替えられるんだなぁ」くらいに思っていただいて OK です。 これを元に、実際に依存関係の制御についてお話していきます。 依存関係の制御 真価を発揮するケース ではこの「 ポリモーフィズムを利用した依存関係の制御 」というのが、どういったケースで協力な武器となるか見ていきます。 まずはじめに以下のようなユースケースを想定し、依存関係の制御をする場合と、しない場合について比較を行います。 ユースケース とあるECサイトを作成するものとします。 そのEC サイトにおいては、以下のような会員ランクの制度があるそうです。 この時、ユーザーが自身の会員ランクを問い合わせる機能を実装します。 具体的な実装の流れとしては以下のような感じになりそうです。 ControllerがBusinessRuleに対して会員情報を渡してランクを問い合わせる DB からユーザー情報に紐づく購入履歴を参照する 購入数や購入金額の情報を受け取る 購入数や購入金額から会員ランクを算出 Controllerへ会員ランク情報を返す 依存関係の制御を行わない場合 構成としては以下のようになりそうです。 (※厳密な UML 図ではないです。) それぞれのクラスの役割は以下の通りです。 Controller リクエストを受けてユーザー情報を BusinessRule へと渡す Business Rule 購入履歴から会員ランクを判定する Database Access DB へのアクセッサーを担う この時の「制御」と「依存」の関係性を図に加えたいと思います。 なお、この時の制御と依存の定義としては以下の通りです。 制御 メソッドを呼び出して実際に利用する関係 依存 呼び出す関数を含むモジュールに言及している関係 C#でいえば using, Java でいえば import を使っていれば依存関係といえます。 Business Rule が Database Access に対して 制御 も行っていますし、 依存 もしている関係性であることが分かります。 ただ、別にこれでも実装自体は行えますし、動作に特段支障も出ないかと思います。 依存関係の制御を行う場合 では先ほどのケースに 依存関係の制御 を行いたいと思います。 Database Access クラス用に Interface を追加し、それを実装する形にします。 そして、Business Rule のクラスからは Interface を参照するようにします。 図としては以下のような形ですね。 この時、改めて制御と依存の関係性を見てみたいと思います。 ここでポイントなのが、 Business Rule と Interfaceを一つの塊 として見ることです。 Interface を挟み込み、依存関係の制御を行うことで 依存関係が Database Access –> [Business Rule + IDatabase Access]  という方向に逆転していることが分かります。 これこそが「 ポリモーフィズムを利用した依存関係の制御 」になります。 Interface を挟み込むことによって、開発者が自由自在に依存関係の制御を行えることができるようになるのです。 メリット 依存関係を制御できることによって、何が嬉しいのでしょうか? 一番のメリットとしては、 依存関係を反転することで「購入履歴から会員ランクを判断する」という ビジネスにとって重要なルールが実装されている Business Rule クラス が何者にも依存しなくなること です。 このルールはビジネスにとって非常に大切なものであり、Databaseの切り替えや、ルールを使う側の都合によって、修正が入ることは望ましくありません。 依存方向を変更することで、Business Rule クラス が Database Access クラス の存在を知る必要がなくなり、Database Access クラスの修正や差し替えが非常に容易になります。 例えば 元々はMySQL を使っていたけど Oracle に切り替えたい テスト用にダミーデータに差し替えたい といった事も Business Rule クラスの修正なしに、簡単に行えるようになります。 なぜなら、Business Rule クラス が依存しているのはIDatabase Accessというインターフェイスであり 実際にDatabaseにアクセスするためのクエリが書かれているのは、それを実装しているクラス(Oracle Database Access, MySQL Databas Access etc.)であるためです。 Business Rule クラス からしたら、インターフェイスを実装したクラスがどのような実装になっているか知らないですし、知る必要がありません。 そのため、Database Access クラス の実装がどう変化しようと、 Business Rule クラス の実装に影響は受けないのです。 なおこのように、 依存する先をインターフェイスのような安定した抽象にすることを「 依存関係逆転の原則(Dependency inversion principle) 」と呼びます。 この「安定した抽象」という表現についてですが、 「抽象」に関しては、Interface を指しています。(今回であれば IDatabaseAccess) 対極にある言葉としては「具象」であり、これは Interface を実装したクラスを指します。(今回であれば MySQLDatabaseAccess など) 「安定した」については、書籍には以下のような記載がありました。 優れたソフトウェア設計者やアーキテクトは、インターフェイスの変動制をできるだけ抑えようとする。新しい機能を実装するときにも、できる限りインターフェイスの変更なしで済ませられるようにする。 安定したソフトウェアアーキテクチャは、変化しやすい具象への依存を避け、安定した抽象インターフェイスに依存するべきである。 つまり、インターフェイスは極力修正の必要がない( =安定している状態) ように設計を行うべきということが分かります。 また、このような実装をすることで、インターフェイスに依存するBusiness Ruleのコードの修正も必要なくなることが分かりました。 このように、 コードを修正する際に不要な影響を及ぼさない依存関係性にすることを「 オープン・クローズドの原則(Open Closed Principle) 」と呼びます。 以上のことから、ポリモーフィズムを利用して依存関係を制御し、関係性を逆転させて安定した抽象への依存とすることで Business Rule の周りがどのようにに変更されようとも、Business Rule に修正を加える必要がなくなり、システムの改修が容易になるのです。 インスタンスの生成 これまで述べてきたような事を実現するためには、 IDataAccess dataAccess = new MySQLDataAccess(); といったような実装をどこかに加えなければいけません。 ただ、これを Business Rule の中に入れてしまっては、結局 MySQLDatabaseAccess に依存する形となってしまい、元も子もありません。 これを解決する実装方法に関しての詳細は今回触れませんが DI コンテナーを利用する Abstract Factory パターンを利用する といった対応をすることで、依存関係を保ったままインスタンスの生成を行うことができます。 まとめ 今回は、オブジェクト指向プログラミングの強力な強みである「 ポリモーフィズムを利用した依存関係の制御 」について説明しました。 「 抽象であるインターフェースに依存するように、ポリモーフィズムを使って依存関係を制御しよう 」ということでした。 是非このあたり意識して設計の方を行っていきたいですね。 ではまた! 参考文献 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post オブジェクト指向の強力な武器 ~依存関係の制御~ first appeared on SIOS Tech. Lab .
アバター
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 BMW に搭載される最新の OS が Linux ベースから Android へ変更されました。 LinuxからAndroidへ「BMW」車載OSの劇的変化 https://toyokeizai.net/articles/-/743299/ 4/18、バッファロー製のルータで脆弱性が確認されました。 現在ご利用中の方はファームウェアのアップデートを実施ください。 バッファロー製Wi-Fiルーターに脆弱性 IPAなどが注意呼び掛け 「最新版ファームウェアへ更新を」 https://www.itmedia.co.jp/news/articles/2404/18/news143.html 4/18、さくらインターネットは IaaS 型パブリッククラウドである「さくらのクラウド」で Red Hat Enterprise Linux の提供を開始しました。 さくらのクラウドで「Red Hat Enterprise Linux Server」を提供開始 https://news.mynavi.jp/techplus/article/20240418-2929655/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2024年4月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
アバター
今号では、curl コマンドのオプションについてちょっと詳しくご紹介します! 2022年 7月 27日にご紹介した「 知っておくとちょっと便利!curl コマンドの使い方をご紹介 」 では、よく使用されると考えられるオプションの意味や使い方について簡単にご説明しましたが、 今回は表示される内容を、ちょっと掘り下げて見ていきます。 -o オプション (コンテンツをファイル出力する) 取得したコンテンツをファイル出力します。 各項目の意味について、それぞれ確認していきます。 $ curl http://example.com -o examplefile % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 27 100 27 0 0 3879 0 --:--:-- --:--:-- --:--:-- 4500 $ cat examplefile This is example index page ※ Time という項目が 3つあるため、それぞれ色を変更して表示しています。 ・ % Total:  全データ量に対する、ダウンロード済みデータ量の割合 ・ % Received:  受信した全データ量に対する、ダウンロード済みデータ量の割合 ・ % Xferd:  送信する全データ量に対する、送信済みデータ量の割合 ・ Average Speed:  ダウンロードもしくはアップロードの平均速度 (1秒あたり) ・ Time :  これまでにかかった時間 ・ Time :  全体のダウンロードもしくはアップロード時間 ・ Time :  残りのダウンロードもしくははアップロード時間 ・ Current:  現在のダウンロードもしくはアップロード速度 (1秒あたり) -v オプション (コンテンツ取得時の詳細なログを表示する) コンテンツを取得した際の詳細なログ (レスポンスヘッダの内容や HTTP ステータスコード等) を表示します。 各項目の意味について、それぞれ確認していきます。 $ curl -v http://example.com 1  * About to connect() to example.com port 80 (#0) 2  * Trying 127.0.0.1... 3  * Connected to example.com (127.0.0.1) port 80 (#0) 4  > GET / HTTP/1.1 5  > User-Agent: curl/7.29.0 6  > Host: example.com 7  > Accept: */* 8  > 9  < HTTP/1.1 200 OK 10  < Date: Wed, 20 Jul 2022 20:12:42 GMT 11  < Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips 12  < Last-Modified: Wed, 20 Jul 2022 19:15:01 GMT 13  < ETag: "1b-5e4416af2a4ab" 14  < Accept-Ranges: bytes 15  < Content-Length: 27 16  < Content-Type: text/html; charset=UTF-8 17  < 18  This is example index page 19  * Connection #0 to host example.com left intact ※各項目についての説明をするため、左に番号を記載しています。 ・ 1 行目:  接続しようとしている URL (example.com) およびポート (80) ・ 2 行目:  接続しようとしている IP アドレス (127.0.0.1) ・ 3 行目:  記載の URL (example.com)、IP (127.0.0.1) に接続完了 ・ 4 ~ 8 行目:  リクエストヘッダの内容   4 行目: HTTP メソッド (GET)、HTTPバージョン (1.1)   5 行目: curl のバージョン (7.29.0)   6 行目: リクエスト先のホスト名   7 行目: レスポンスを受け取る際に、受け入れを許可するコンテンツタイプ       (この場合、すべてのコンテンツタイプを許可) ・ 9 ~ 17 行目:  レスポンスヘッダの内容   9 行目: HTTPバージョン (1.1)、ステータスコード (200)、ステータスメッセージ (OK)   10 行目: レスポンスヘッダが作成された日時   11 行目: Web サーバ (この場合は Apache)、および OpenSSL のバージョン   12 行目: コンテンツの最終更新日時   13 行目: エンティティタグ (コンテンツの識別子)   14 行目: Range に対応している (コンテンツの特定部分のみをリクエストできる) 旨を示す   15 行目: レスポンスボディのサイズ (単位:byte)   16 行目: レスポンスボディの種類 (この場合は HTML 形式)、および文字エンコード       (この場合は UTF-8) ・ 18 行目:  コンテンツの内容 なお、 -I オプション を指定した際に出力される内容と、上記 9 ~ 17 行目 で表示される 内容は同じものになっています。 $ curl -I http://example.com HTTP/1.1 200 OK Date: Wed, 20 Jul 2022 20:14:49 GMT Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips Last-Modified: Wed, 20 Jul 2022 19:15:01 GMT ETag: "1b-5e4416af2a4ab" Accept-Ranges: bytes Content-Length: 27 Content-Type: text/html; charset=UTF-8 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!curl コマンドのオプションをちょっと詳しくご紹介 first appeared on SIOS Tech. Lab .
アバター
こんにちは。サイオステクノロジーの橋本です。 今回は RHEL 8、9 において /etc/pam.d/ 配下のファイルや /etc/nsswitch.conf といった認証周りの設定変更方法について実例を挙げつつ説明していきます。 ※今回はそれぞれのファイルの説明は行いません。 ファイルを直接編集しているワイルドな方は今一度手順を見直してください。 時間がない人向けに 大体の場合 root ユーザで /etc/authselect/ 配下の設定を変更し authselect apply-changes コマンドを実行すれば設定は反映されます。 前提 /etc/pam.d/ 配下のファイルや /etc/nsswitch.conf を直接編集することは推奨されていません。 設定ファイルを間接的に編集し、authselect コマンドを用いて設定を反映させる必要があります。 ※似た考え方をするコマンドに GRUB2 の grub2-mkconfig コマンドなどがあります。 サーバの根幹に関わる設定なので安全な設定変更方法を実現しているわけです。 nsswitch.conf の以下の項目を編集したい場合は、新しくプロファイルを作成する必要があります。 passwd、 group netgroup automount services 今回は passwd も変更したいので新しいプロファイルを作成します。 よく使うコマンド RHEL 8、9 では認証周りの設定をプロファイルという形で複数保持することが 可能です。複数ある中から任意のプロファイルを一つ選んで利用するわけです。 まずは利用可能なプロファイル一覧を確認し、 現在選択されているプロファイルとその設定内容を確認しましょう。 ・利用な可能なプロファイル一覧を表示 # authselect list - minimal Local users only for minimal installations - sssd Enable SSSD for system authentication (also for local users only) - winbind Enable winbind for system authentication # ・現在選択されているプロファイルを確認 # authselect current プロファイル ID: sssd 有効な機能: なし # ・プロファイルの内容を確認 # authselect test sssd ファイル /etc/nsswitch.conf: # If you want to make changes to nsswitch.conf please modify # /etc/authselect/user-nsswitch.conf and run 'authselect apply-changes'. # # Note that your changes may not be applied as they may be # overwritten by selected profile. Maps set in the authselect ~後略~ 設定の変更 まずは新しいプロファイルを作成しましょう。 # authselect create-profile newprofile --base-on sssd /etc/authselect/custom/newprofile で新規のプロファイルが作成されました # 上記コマンドでプロファイル sssd をベースとした新しいプロファイルが作成されました。 この段階では「sssd」と「newprofile」の間に設定差はありません。 newprofile の設定内容は /etc/authselect/custom/newprofile 配下にあります。 # ls -la /etc/authselect/custom/newprofile 合計 52 drwxr-xr-x. 2 root root 4096 4月 22 14:36 . drwxr-xr-x. 3 root root 24 4月 22 14:36 .. -rw-r--r--. 1 root root 4633 4月 22 14:36 README -rw-r--r--. 1 root root 3248 4月 22 14:36 REQUIREMENTS -rw-r--r--. 1 root root 540 4月 22 14:36 dconf-db -rw-r--r--. 1 root root 279 4月 22 14:36 dconf-locks -rw-r--r--. 1 root root 2461 4月 22 14:36 fingerprint-auth -rw-r--r--. 1 root root 505 4月 22 14:36 nsswitch.conf -rw-r--r--. 1 root root 3732 4月 22 14:36 password-auth -rw-r--r--. 1 root root 340 4月 22 14:36 postlogin -rw-r--r--. 1 root root 2355 4月 22 14:36 smartcard-auth -rw-r--r--. 1 root root 4778 4月 22 14:36 system-auth # pam 配下のファイル、例えば system-auth の設定を変更したい場合は、 /etc/authselect/custom/newprofile 配下の system-auth を編集した上で、 プロファイル「newprofile」を適用すればいいわけです。 ・変更前 password sufficient pam_unix.so sha512 shadow {if not "without-nullok":nullok} use_authtok ・変更後 password sufficient pam_unix.so sha512 shadow {if not "without-nullok":nullok} use_authtok remember=5 nsswitch.conf の設定の変更 さて問題は一部の nsswitch.conf の設定です。 項目によって設定変更方法が異なります。 以下の項目は /etc/authselect/custom/newprofile/nsswitch.conf で 設定を編集する必要があります。 passwd group netgroup automount services ・変更前 passwd: {if "with-files-domain":sss files|files sss} systemd {exclude if "with-custom-passwd"} ・変更後 passwd: files ldap 設定の内容を確認してみると意図した内容となっているみたいです。 # authselect test custom/newprofile | egrep "password sufficient|passwd: files ldap" passwd: files ldap password sufficient pam_unix.so sha512 shadow nullok use_authtok remember=5 password sufficient pam_sss.so use_authtok password sufficient pam_unix.so sha512 shadow nullok use_authtok password sufficient pam_sss.so use_authtok # プロファイルの変更 この段階でプロファイルを変更してみましょう # authselect select custom/newprofile プロファイル "custom/newprofile" が設定されました。 以下の nsswitch マップはプロファイルで上書きされます: - passwd - group - netgroup - automount - services Make sure that SSSD service is configured and enabled. See SSSD documentation for more information. # 前述の 5 項目 (passwd など) 以外の shadow などは /etc/authselect/user-nsswitch.conf で行う必要があります。 ・編集前 passwd: sss files systemd shadow: files ・編集後 passwd: sss files systemd shadow: files ldap passwd や group などは /etc/authselect/user-nsswitch.conf を編集しても設定は反映されません。 /etc/authselect/custom/newprofile/nsswitch.conf を編集しましょう。 ※設定するファイルがいろいろ分かれているのはちょっと分かりにくいですね。。。。 設定の変更反映 この後、authselect apply-changes で変更した設定を変更させます。 # authselect apply-changes 変更は正常に適用されました。 # 今回は authselect について説明しました。 私が調べた限り事例などは少なく手探りで調べる必要があるコマンドだったので、 どなたかのお役に立てればと思います。 PAM や nsswitch.conf はサーバの認証周りの根幹に関わるので、 慎重に設定してください。 補足 authselect は RHEL 8 以降のコマンドとなります。 RHEL 7 以前は authconfig でした。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post OS の認証周りの設定を変更してみよう ~authselect について~ first appeared on SIOS Tech. Lab .
アバター
こんにちは。サイオステクノロジー OSS サポート担当 山本 です。 今回は Apache Solr (Solr) というやつを試そうとしてみたので、それについてのお話です。 非常に尖った用途を持つ OSS で、(私のように) 使う機会がなければ恐らく馴染みのないものかと思いますが、だからこそ必要になりそうな時に存在を知っていると選択肢が増えそうだなぁ、と思えるものなので、そのあたりを頑張って伝えていきたいと思います。 ■Solr って何? Solr は、 全文検索 というものを行うための OSS です。 全文検索……ってつまりどういうことをするの?というのをものすごくざっくり言うと 「 データを登録 しておいて」後に「 登録済みのデータから検索 を行う」もの です。 リレーショナルデータベース ( RDB ) をご存じであれば、それに近いことをやるのかな、とイメージするとわかりやすいかもしれません。 大まかな流れを先に確認してみましょう。 Solr では基本的に、まず登録するデータに合わせて スキーマ と呼ばれる型 を作成します。 スキーマは 複数の フィールド から成り、それぞれのフィールドには “フィールド名” や “型 (文字列、数値など)” などを設定します。 例えば、”料理” のスキーマならフィールドは “名前”、”材料”、”調理時間目安”、”調理手順”……など、”本” のスキーマならばフィールドは “タイトル”、”著者”、”発表年”、”冒頭文”、”概要”……などが考えられます。(実際には登録するデータに合わせて考える必要があります。) スキーマを作成したら、決められた書式に合わせて 用意しておいたデータを登録 します。 (こうして Solr に登録したデータは、 ドキュメント と呼ばれます。) ここまでが前準備です。 そうしたら、Solr に対して問い合わせ ( クエリ ) を発行すると、該当する ドキュメント を結果として返してくれる……というわけです。 Solr でやること・やれることは、極めて大まかにですが大枠としては以上です。 用語こそ違えど、概要を見る感じは RDB と似たようなもの ですね。 では改めて Solr の、というか全文検索の特色は何かと言うと…… 文字列検索に特化している ことです。 例えば、先に挙げたスキーマ例で言えば 「”名前” “材料” “調理手順” の いずれか に『蒸し』を 含む ドキュメント」 のような検索を、solr は 極めて高速に 行うことができます。 RDB でも “LIKE 句” によって同じようなことはできますが、原則として RDB はこのような「特定の文字列を含む」という検索は得意とはしておらず、検索対象の DB サイズが大きくなるほど極端に遅くなりがちです。 また Solr は、例えば「いちご」で検索することで「イチゴ」「苺」「ストロベリー」を含むドキュメントも検索できるようにするような 同義語・類義語検索や、あいまい検索などを実現 できる仕組みなど、 我々が「検索」と聞いたときにイメージするような機能を実現 できるものになっています。 逆に Solr は、集計や結合処理などの RDB の得意とするような処理には適しているとは言えません。 ところで、Apache のソフトウェアの中には Solr と同じく全文検索のための OSS である Lucene というものが存在しています。 Solr の話を見ていると稀に名前の出てくるこの Lucene についても簡単に触れておくと、 Lucene は Java (および Python) 向けの組み込みライブラリの OSS であるのに対して、 Solr は Lucene をベースにしている派生の OSS であり、 Web API や Web UI などを備えるサーバ向けアプリケーション です。 Solr では Lucene でできることは概ねできる、とされており、単体で動かせるアプリケーションであることからも、とりあえず「全文検索」がどんなものか体感したいのであれば Solr を試してみるのがよいかと思います。 ■Solr をほんの少しだけ試してみる さて、ざっくり概要についてお話ししてみましたが、話だけではわかりにくいと思うので少し試してみましょう。 Solr を試すなら、 公式の配布しているコンテナイメージ を使うのが恐らく最も手軽でしょう。 今回は Red Hat Enterprise Linux 9 環境で Podman を使って試してみます。 コンテナイメージが現在どこで配布されているかやコンテナ以外での導入方法については、公式の ダウンロードページ から確認してください。 さて、Podman を導入済みであれば、以下のようなコマンドを実行すれば デモ用データ付きの Solr を立ち上げることができます。簡単ですね。 $ podman run -dt --name test-solr -p 8984:8983 solr solr-demo 実行したら、まずは管理用の Web UI に接続してみましょう。 任意の Web ブラウザを立ち上げ、(上記の例で立ち上げた場合は) 以下のような URL にアクセスしてみましょう。 http://(IPアドレス or ホスト名):8984/solr すると、このようなページが表示されるはずです。 表示された管理用画面ではいろいろなことができますが、とりあえず今回はデモ用データの確認できるクエリのページだけ確認しておきましょう。 この画面の画面下部にある “ Execute Query ” ボタンを押下すると、登録されているデモ用データの一覧が表示されるはずです。 (UI で条件を指定してやれば、条件に合致したものだけが表示されます。) 一方、 既定の URL へのアクセス によって直接検索結果を取得することもできます。 例えば、デモ用データの中から “name” フィールド に「drive」を含むものを取得したいなら、デモ用データのある コア ( ドキュメント を入れる大枠のようなもの) は “demo” という名前になっていますが、この場合は以下のようなアドレスにアクセスすれば OK です。 http://(IPアドレス or ホスト名):8984/solr/demo/select?q=name%3Adrive ※ “%3A” = “: (コロン)” を URL エンコードしたもの 例として、Podman で Solr を実行したホスト上から curl を使って先述のアドレスへアクセスすると、以下のようにデフォルトの JSON フォーマットでの結果が返ってくるはずです。 $ curl 'http://localhost:8984/solr/demo/select?q=name%3Adrive' { "responseHeader":{ "status":0, "QTime":41, "params":{ "q":"name:drive" } }, "response":{ "numFound":2, "start":0, "numFoundExact":true, "docs":[{ "id":"6H500F0", "name":["Maxtor DiamondMax 11 - hard drive - 500 GB - SATA-300"], "manu":["Maxtor Corp."], "manu_id_s":"maxtor", "cat":["electronics","hard drive"], "features":["SATA 3.0Gb/s, NCQ","8.5ms seek","16MB cache"], "price":[350.0], "popularity":[6], "inStock":[true], "store":["45.17614,-93.87341"], "manufacturedate_dt":"2006-02-13T15:26:37Z", "_version_":1796378465704869888 },{ "id":"SP2514N", "name":["Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133"], "manu":["Samsung Electronics Co. Ltd."], "manu_id_s":"samsung", "cat":["electronics","hard drive"], "features":["7200RPM, 8MB cache, IDE Ultra ATA-133","NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor"], "price":[92.0], "popularity":[6], "inStock":[true], "manufacturedate_dt":"2006-02-13T15:26:37Z", "store":["35.0752,-97.032"], "_version_":1796378465692286976 }] } } ■最後に 今回はそもそも Solr とはどんなものか、ということを中心にお話ししてみました。 検索機能を作りたい時に使うのかなぁ、となんとなく伝わったでしょうか?多数のページで構成された、公開するためのサイト……例えばマニュアル・ヘルプだったり、EC などを作る場合には利便性を確保するための選択肢として強力に働いてくれるハズです。 なお、今回の話の中で出てきた RDB や Podman ってのは何なんだ、という方は以下の別記事も見ていただけたら幸いです。 わからないなりに理解したいデータベース①:RDB編:MySQL① わからないなりに理解したい Podman ① ~ 何をするもの? ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Solr って何者?①:Solr って何?? first appeared on SIOS Tech. Lab .
アバター
PSの米谷俊輔です。 今回はWeb3.0における デジタルアイデンティティ を管理する技術、DIDsについて調べてみましたので解説します。 DIDsとは DIDs (分散型識別子: Decentralized Identifiers) は、分散型台帳技術 (主にブロックチェーン) を使った識別子 (IDを識別するための情報) です。 Web2.0までのように認証サービスを提供する IDプロバイダー (IdP) に依存せず、利用するユーザが自身の デジタルアイデンティティ ※1 を管理し ※2 、国や事業者等に掲示する情報をユーザー自身が制御することができます。 DIDsは SSI (自己主権型アイデンティティ: Self-Sovereign Identity) ※3 を実現する手段として注目されています。 ※1: デジタル化した個人などに関連した属性情報 (例: ID、パスワード、メールアドレス) の集合 ※2: 実際の運用において学歴や資格等の情報は有効かつ信頼性のある方法で検証が必要であり、信頼できる認証機関やデータ提供者が関与することが求められます。 ※3: 国や事業者等の認証機関や管理者に依存することなく、自身の個人情報を自身で管理・保管を行い、あらゆる決定権を持つべきであるとする考え方。 以降の説明の理解を深めるためにDIDsとDIDの違いについて最初に説明します。 DIDとDIDsの違い Web3.0においてDecentralized IdentifiersはDIDまたはDIDsと表記されます。この表記はDIDを理解する上で障害になることがあります。 DIDは「分散型アイデンティティ: Decentralized Identity」、「分散型識別子: Decentralized Identifier(s)」と異なる意味の複数の言葉を示す略語として使用され、いずれの意味であるかは文脈から理解する必要があります。一方DIDsは「分散型識別子: Decentralized Identifiers」を示す略語であり、意味を明確にしたい場合に利用する傾向があります。 この記事では Decentralized IdentifiersはDIDs で統一して表記します。 次からDIDsについて解説を始めます。最初にDIDsの特徴です。 DIDsの 特徴 DIDsは SSIを実現する手段であることは前述しましたが、 SSIでは以下の「SSIの10原則」 ※4 が提唱されております。 ※4: 2016年にSSL/TLSの専門家であるクリストファー・アレン氏が「The Path to Self-Sovereign Identity」の記事中で提唱した原則 No. 原則 説明 1 実在 (Existence) ユーザーは独立した存在である。 2 コントロール (Control) ユーザは自身のIDを管理することができる。他のユーザがIDを管理する存在であってはならない。 3 アクセス (Access) ユーザーは自身のIDに紐づくすべてのデータにアクセスすることができ、ユーザーに隠されたデータや制限がない。 4 透明性 (Transparency) IDを管理・更新するシステムおよびアルゴリズムは透明性が担保されている。 5 持続性 (Persistence) IDは永久に、少なくともユーザーが望む限り存続する。これは「忘れられる権利」と矛盾しない。 6 携帯性 (Portability) IDに紐づくすべてのデータはサービス間で利用可能である。またユーザが自身のIDを管理し続けられることを保証する。 7 相互運用性 (Interoperability) IDは可能な限り広く利用できる。 8 同意 (Consent) IDに紐づくすべてのデータは共有される際にはユーザの同意が必要である。 9 最小化 (Minimalization) IDに紐づくすべてのデータは開示範囲を最小限とする。 10 保護 (Protection) ユーザの権利は保護されなければならない。ID ネットワークのニーズよりも個人の自由と権利が優先される。 出典: https://www.w3.org/TR/did-core/#design-goals 「SSIの10原則」を私的にまとめるとSSIは、「特定の国やシステムに依存しない独立した存在である。」、「ユーザーは自身のIDに紐づくすべてのデータを把握し、管理することができる。 」、「様々なサービス間で相互運用が可能で、ユーザーが望む限り存続する。」、「SSIに紐づいたデータの提示はユーザの同意が必要、且つ最小限の範囲に限られる。」 、「これらを実現するSSIを管理するシステムおよびアルゴリズムは堅牢かつ透明性を担保されている。」といった特徴があると考えます。 SSIを実現する手段である DIDsはこの原則に準じた特徴を持つと考えられます。 またDIDsは 国際技術標準化団体のW3C (World Wide Web Consortium) により2022年7月19日に「Decentralized Identifiers (DIDs) v1.0」として標準規格が公表されました。W3Cが定めた標準規格はDIDsを理解・利用する上で重要な基準となると考えます。 「Decentralized Identifiers (DIDs) v1.0」の要旨(全文は こちら ) では 「SSIの10原則」の他に 「 DIDsは検証可能な分散型デジタルIDを可能にする新しいタイプの識別子である。 」、「DIDsは、DID subjectと DID documentを関連付けるURIであり、その表題に関連する信頼できるやり取りを可能にする。」の特徴が追加されています。 「DIDsは検証可能な分散型デジタルIDを可能にする」という特徴からDIDsには、検証可能なID、検証不可能なID、検証可能だが検証しないIDがあるということが分かります。検証可能なIDとは氏名、住所、血液型、生年月日、写真、認証番号、資格、学歴、職歴、病歴などパーソナリティに結びつくIDのうち、行政や信頼できる機関より検証に必要なデータが発行されるものが対象となります。 検証可能な 分散型デジタル IDを実現するために必要とされている技術が VC (検証可能な資格情報: Verifiable Credentials) です。 VCとは VCは 行政 や信頼できる機関より発行されたデータを使い安全にIDの真正を検証する技術およびフォーマットであり情報そのものとは異なります。 VCもDIDsと同様にW3Cの「 Verifiable Credentials Data Model v2.0 」により標準規格が公表されています。 「Verifiable Credentials Data Model v2.0」におけるVCの仕組みについて解説します。 VCの仕組み 「Verifiable Credentials Data Model v2.0」ではVCの仕組みの一例を以下の図のように表しています。 図1. The roles and information flows forming the basis for this specification. 出典: Verifiable Credentials Data Model v2.0 | W3C 図1には3人の人物「Issuer」 (発行者)、「Holder」 (保有者)、「Verifier」 (検証者) および1つのデータベース「Verifiable Data Registry」 (検証可能なデータの保管データベース) が登場します。VCの仕組みにおけるそれぞれの役割は以下の通りです。 Holder (保有者) DIDの利用ユーザ―を想定 Verifiable Data Registryにスキーマを利用してID情報を登録します。Issuerに対しID情報に対するVCs ( VCで検証されるデジタル証明書 ) の発行を依頼します。 Issuerが発行したVCsを保管し、Verifierに対しID情報およびVCsを提示します。 Issuer (発行者) 行政や信頼できる機関等の検証に必要なデータの発行元を想定 Holderの依頼を受けてVerifiable Data Registryに登録されたID情報を検証し、VCsを発行します。 Verifier (検証者) 認証システム等、HolderのID情報を要求元を想定 Holderが提示したID情報に対しVerifiable Data Registryに登録されたスキーマおよびID情報を検証します。 Holderが提示したVCsを検証します。 Verifiable Data Registry (検証可能なデータの保管データベース) スキーマおよびID情報を保持します。 VCの仕組みによりVerifierはIssuer問い合わせることなく、Holderが提示したID情報の検証を行うことができます。 まとめ DIDsの解説をまとめると以下となります。 DIDsは、分散型台帳技術を使った識別子です。 DIDsは 「SSIの10原則」 に準じた特徴を持つと考えられる。 「Decentralized Identifiers (DIDs) v1.0」はW3Cにより公表されたDIDsの標準規格である。 DIDsの 検証可能な 分散型デジタル IDを実現する技術が VC である。 VCとDIDsを組み合わせることでID情報の真正が保証される。 いかがでしたでしょうか。今回はDIDsから関連すSSIやVCの簡単な解説を行いました。DIDsやVCについてはこれからもさらに技術的な解説を行う予定です。 Web3.0時代のID であるDIDsが社会に普及することによりID情報の主導権はユーザー自身の手に取り戻されることが期待されます。また今までID情報を管理してきたIdPは個人情報流出のリスクから解放されることが考えられます。今後もDIDsをはじめとしたブロックチェーン技術について注目していきたいと思います。 参考URL Decentralized Identifiers (DIDs) v1.0 The Path to Self-Sovereign Identity Verifiable Credentials Data Model v2.0 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Web3.0時代のID、DIDsについて調べてみたので解説してみた first appeared on SIOS Tech. Lab .
アバター
こんにちは、サイオステクノロジー武井です。今回は、今ナウくてあつい「プロンプトエンジニアリング」について一筆したためました。 プロンプトエンジニアリングとは? 「プロンプトエンジニアリング」という言葉を聞いたこといらっしゃる方いると思います。米国では「プロンプトエンジニア」という職種は数千万の年収をもらえるという噂も聞きます。 OpenAIが提供するChatGPTや、マイクロソフトのBing Chatはプロンプトの与え方が良い回答を引き出すための成否を分けると言っても過言ではありません。正確な回答を引き出すためのプロンプトを上手に作成出来る技術を「プロンプトエンジニアリング」と呼び、そのためのテクニックはいくつかありまして、代表的なものを以下に記載します。 Few-shot Learning 少数の例文から新しいタスクに対して高精度な回答を出力する技術です。例えば、ChatGPTでは、少数の例文から新しい文章を生成することができます。 Zero-shot Learning 事前学習されたモデルに対して、新しいタスクに対する指示を与えることで回答を出力する技術です。例えば、「英語で書かれた小説を日本語に翻訳してください」という指示を与えることで、モデルは自動的に翻訳を行います。 ReAct 言語モデルでさまざまな言語推論や意思決定を遂行する手法です。行動理由の「推論」と「行動」の組み合わせにより、より高度なタスクを処理することができます。 この他にもたくさんあります。 牛タンゲームでプロンプトエンジニアリングを学ぶ 上記の中でよく利用するものの1つである「Few-Shot Learning」を例に、プロンプトエンジニアリングについてさらに詳しく説明します。 これは何よりも実例をあげるのが一番です。そこで、伝説のアイドル「広末涼子」さんが流行らせたという「牛タンゲーム」を題材にしてFew-shot Learningを解説します。 「牛タンゲーム」は、合コンや宴会などで行われる余興の1つです。牛タンゲームのルールをご存じの方は、この後の牛タンゲームの説明は読み飛ばしていただいて構いません。そうでない方はちょっとお付き合いください。 で、牛タンゲームの説明ですが、まず最初の人が「牛(ぎゅう)」と発言し、次の人間は「タン」と手をたたきます(このとき「タン」とはいいません)。次の人は再び「牛」といい、次の人は「タン」と手をたたきます。 そして、また次の人は「牛」といって、次の人、次の次の人も「タン」と手を叩きます。 ここまでで、「牛・タン・牛・タン・牛・タン・タン」となり、1ターン目が終了します。 その後は、3回目の「タン」をターンごとに増やしていきます。 例えば、Aさん、Bさん、Cさん、Dさんの4人がこの順番で牛タンゲームを始めた場合、その役割分担は以下のとおりになります。 おわかり頂けましたでしょうか?ぜひ皆さんもご家族・ご友人同士で試してみてください。 今回、ChatGPTに以下の質問をしてみます。 牛タンゲームをAさん、Bさん、Cさん、Dさんの4人でこの順番で始めたときに、3ターン目で最後に手を叩くのは誰ですか? 以下の図のとおり、期待するべき回答はDさんです。 では、ChatGPTに聞いてみましょう。 さすがに人類の叡智を極めたChatGPTでも、牛タンゲームの内容は知らなかったようです。回答も誤っていますし、なんだかさも涼しい顔をして、謎の独自ルールを解説しています。僕たちの知っている牛タンゲームはこんなんじゃないはずです。 そこで、Few-shot Learningの出番です。 ChatGPTがうまく答えられないことについては、事前知識と模範的な回答例をいくつか与えて学習させることで、正確な回答をすることが出来るようになります。これがFew-shot Learningと言われるものです。 早速実践してみます。以下の質問をChatGPTにしてみます。 最初の「#ルール」で、牛タンゲームのルールという事前知識を与えた上で、「#サンプル」で牛タンゲームの模範的な実践例をさらに与えています。これでChatGPTに学習をさせているわけです。先の質問に対する回答は以下のようになります。 ずばり、正解です!! このような学習をモデルにさせるためには従来は「ファインチューニング」という手法が取られていました。しかしながら、ファインチューニングにはいくつかの問題点があります。新しいタスクに適応させるためのモデルの訓練には、そのタスクに関連する大量のデータが必要でした。データの収集、整理、前処理は時間とリソースを大きく消費するプロセスでした。また、データが不足している場合、モデルは学習データに過度に適応してしまうオーバーフィッティングのリスクが高まり、これが実際の適用時に性能の低下を引き起こすことがありました。さらに、新しいタスクに対してモデルを再訓練するための計算リソースも必要とされ、これが追加のコストと時間を必要としました。 一方で、Few-shot Learningの登場により、これらの問題点が大きく緩和されました。この手法の魅力は、非常に限られたデータセットでも新しいタスクを効果的に学習できる点にあります。事前に大規模なデータセットで訓練されたモデルの知識を利活用することで、新しいタスクにも迅速に適応することが可能となりました。この方法は、新しいタスクのデータ収集の手間や、再訓練に伴う計算リソースのコストを大幅に削減する利点があります。 Few-shot Learning素晴らしいですね。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 牛タンゲームでプロンプトエンジニアリングを学ぶ first appeared on SIOS Tech. Lab .
アバター
はじめに こんにちは、サイオステクノロジーのあさりです。今回は、django-admin-rangefilterというパッケージを使って、DjangoAdminのモデル一覧画面でカレンダー形式での日付の範囲指定を行えるフィルターを実装する方法を紹介します。 環境 Python3 Django4.2 django-admin-rangefilter 0.10.0 DjangoAdminのフィルター機能について DjangoAdminでは、以下のようにlist_filterでフィールドを指定するとそのフィールドに基づいた絞り込みが可能になります。今回は、例として こちら の記事で作成したAccessLogモデルを使用します。 # accesslog/admin.py from django.contrib import admin from .models import AccessLog class AccessLogAdmin(admin.ModelAdmin): list_display = ('access_date_time', 'request_url', 'request_method',) list_filter = ('access_date_time',) #フィルター機能を利用するフィールドの指定 admin.site.register(AccessLog, AccessLogAdmin) list_filterの設定完了後に次のコマンドでサーバーを立ち上げて、どのようなフィルターが実装されているか確認してみましょう。 python3 manage.py runserver アクセスログの一覧画面を確認すると以下のようなフィルターが実装されていると思います。 list_filterに指定したaccess_date_timeフィールドはDateTimeFieldで定義されており、DateTimeFieldに対しては画像のような5つの選択肢を持つフィルターが実装されるようです。しかし、このデフォルトのフィルターでは先月や昨年のデータの絞り込みを行いたいときに不便だなと感じます。 そこでdjango-admin-rangefilterというパッケージを導入して、日付を範囲指定して絞り込みを行えるフィルターを実装したいと思います。 django-admin-rangefilterによるフィルターの実装 パッケージのインストール まずは、パッケージをインストールしましょう。 pip install django-admin-rangefilter 設定ファイルに追加 次に、インストールしたパッケージをプロジェクト内で有効化するために設定ファイルのINSTALLED_APPSにrangefilterを追加します。 # settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'accesslog', 'rangefilter', ] フィルターの実装 rangefilterを使って、access_date_timeについてカレンダー形式で日付の範囲指定を行えるフィルターを実装するには、admin.pyを次のように編集してください。 # accesslog/admin.py from django.contrib import admin from rangefilter.filters import DateRangeFilter from .models import AccessLog class AccessLogAdmin(admin.ModelAdmin): list_display = ('access_date_time', 'request_url', 'request_method',) list_filter = (('access_date_time', DateRangeFilter),) #フィルター機能を利用するフィールドの指定 admin.site.register(AccessLog, AccessLogAdmin) 実装はこれで完了です。 動作確認 サーバーを立ち上げて、フィルターが実装できているか確かめてみましょう。 カレンダーアイコンから開始日と終了日の指定ができ、検索ボタンとリセットボタンも実装されていると思います。 おわりに 今回は、django-admin-rangefilterを使って、カレンダー形式で日付の範囲指定を行えるフィルターを実装しました。デフォルトのフィルターに比べて便利で導入も簡単なのでぜひ試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DjangoAdmin モデル一覧画面で日付の範囲指定を行えるフィルターを実装してみた first appeared on SIOS Tech. Lab .
アバター
こんにちは、サイオステクノロジーの佐藤 陽です。 今回は、ASP.NET Core入門シリーズ第三弾として、 ミドルウェア と リクエストパイプライン について書いていきたいと思います。 コントローラーじゃないところでリクエストに共通処理を追加したい! ミドルウェアって何? リクエストパイプラインって何? という方はぜひ最後までご覧ください。 また前回の記事から繰り返しになりますが まだ自分も勉強中の身なので、記事の内容に誤りなどありましたらコメントにて指摘いただけると幸いです。 はじめに 今回のテーマは ミドルウェア と リクエストパイプライン です。 「コントローラー等のアプリケーションコードはガシガシ書くけど、パイプライン周りは触ったことない」という方も多いのではないでしょうか? 前回の記事の中にもMiddlewarePipelineというワードが何回か出てきました。 リクエストを処理するにあたって非常に重要な仕組みであるため、このあたりもしっかり追っていきたいと思います。 ミドルウェアとリクエストパイプラインとは ミドルウェア とは、ソフトウェアコンポーネントです。 そして、それらのミドルウェアを連ねたものが リクエストパイプライン と呼ばれています。 前回の記事 でも紹介したインプロセスホスティングの場合のASP.NET Coreの動作の図を例にみると ASP.NET Core のアプリケーションに対するリクエストは、 コントローラ(Application Code) で処理される前に、 リクエストパイプライン(Middleware Pipeline) にて順々に処理されます。 ※表記揺れがあって申し訳ないですが、コントローラとApplicationCode, リクエストパイプラインとMiddleware Pipelineは同義として扱います。 リクエストパイプラインの内部をもう少し詳細に見てみると、以下のような形となります。 このリクエストパイプラインの仕組みを利用することで、 コントローラでの処理の前処理および、後処理を実装することが可能となります。 パイプラインの構築方法 ではこのリクエストパイプラインが、どのように実装されているかを見ていきたいと思います。 扱うプロジェクトとしては、 前回の記事 でも作成したMVCのプロジェクトとしたいと思います。 リクエストパイプラインを構成するソースコードとしては、Program.csファイルの中に書かれています。 ( 汎用なホスト を利用している場合は、Startup.cs の Configureメソッド内に書かれます) プロジェクトのProgram.cs の中身を抜粋します。 var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) {     app.UseExceptionHandler("/Home/Error");     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.     app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute(     name: "default",     pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); この時、 app 変数は WebApplication クラスのインスタンスです。 前回の記事の復習になりますが、このWebApplicationクラスの役割としては以下2つのものがあります。 リクエストパイプラインの構築 ホストの開始 このWebApplicationのインスタンスと、Use, Run, Mapといったような拡張メソッドを利用してパイプラインを構築していきます。 なお、ミドルウェアの定義に関しては①インラインで定義する方法と、②再利用可能なクラスとして定義する方法の2種類があるため、それぞれについて見ていきたいと思います。 インライン定義での追加 まずはインラインで定義したミドルウェアの追加方法を紹介します。 拡張メソッドである UseExtensions.Use を利用して以下のように書きます。 await next.Invoke() を境として、前処理なのか後処理なのかを区別することができます。 app.Use(async (context, next) => { //ここにコントローラで処理される前に行う処理を書く //次のミドルウェアへと遷移する await next.Invoke(); //ここにコントローラでの処理が行われた後に行う処理を書く }); 余談ですが、Use拡張メソッドの引数はIApplicationBuilder型となっています。 public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, RequestDelegate, Task> middleware) 「Program.csにおいてappはWebApplicationクラスだから型が違うのでは?」 と思われる方もいるかもしれませんが、 WebApplication はIApplicationBuilderのInterfaceを実装しているので、ここは問題なしです。 再利用可能なクラスによる追加 インライン定義での追加はサクッとできてお手軽なのですが やはり可読性や再利用性などを考えた場合、事前に再利用な可能なクラスにまとめて使いまわす方が得策とされています。 本章では事前に定義したミドルウェアを追加していく方法を見ていきたいと思います。 なお事前に定義したミドルウェアとしては「 組み込みミドルウェア 」と「 カスタムミドルウェア 」があるため、それぞれについて見ていきます。 組み込みミドルウェア ASP.NET Coreにおいては 組み込みミドルウェア コンポーネント が豊富に提供されています。 先ほど見たProgram.csにおいて書かれているミドルウェア群も、組み込みミドルウェアの一例になります。 ここでは実際に UseHttpsRedirection のメソッドを例にしてソースコードを見てみたいと思います。 UseHttpsRedirectionの ソースコード を見ると、Summaryとして Adds middleware for redirecting HTTP Requests to HTTPS. と記載されていることから、ミドルウェアに追加するためのメソッドであることがわかります。 またこちらのソースコードの中身を見てみると、Useメソッドと同じような形で拡張メソッドとして定義されていることがわかります。 public static IApplicationBuilder UseHttpsRedirection(this IApplicationBuilder app) { ArgumentNullException.ThrowIfNull(app); var serverAddressFeature = app.ServerFeatures.Get<IServerAddressesFeature>(); if (serverAddressFeature != null) { app.UseMiddleware<HttpsRedirectionMiddleware>(serverAddressFeature); } else { app.UseMiddleware<HttpsRedirectionMiddleware>(); } return app; } この時、コード内において app.UseMiddleware<HttpsRedirectionMiddleware>(serverAddressFeature); と実行している場所があります。 ここで書かれている HTTPsRedirectionMiddleware というのが 事前定義されたミドルウェア本体 であり、 UseMiddlware<TMiddleware> メソッドを利用して追加していることが分かります。 他の UseStaticsFiles() メソッドなども同様の形で拡張メソッドとして定義されており これらのメソッドを通して、組み込みミドルウェアをリクエストパイプラインへと追加しています。 カスタムミドルウェア 先ほどはASP.NET Core側で用意されている組み込みミドルウェアに言及しましたが もちろん自分でミドルウェアを作成したいようなケースも往々にしてあります。 その際、先ほどのHTTPsRedirectionMiddlewareのようなクラスを自分で定義することが可能です。 ただし、どんなものでもいいわけではなく、作成に当たっていくつかルールが存在します。 公式ドキュメント によると、ミドルウェアは以下のようなものを持つ必要があるとのことです。 RequestDelegate 型のパラメーターを持つパブリック コンストラクター。 Invoke または InvokeAsync という名前のパブリック メソッド。 このメソッドでは次のことが必要です。 Task を返します。 HttpContext 型の最初のパラメーターを受け取ります。 先ほどの HTTPsRedirectionMiddleware のソースコードを見ても、これらが含まれていることが確認できます。 また必須ではないようですが、組み込みミドルウェアのように拡張メソッドを定義してあげることも一般的のようです。 定義してもしなくても性能的な部分では変わりませんが、可読性の向上を目的としているようです。 その際、組み込みミドルウェアと同様の形として ***Extensitons という名称のstaticクラスで定義する Use*** という名称の拡張メソッドを定義する といった形にするかとよいかと思われます。 追加する順番について これまでリクエストパイプラインにミドルウェアを追加する方法について説明してきましたが この ミドルウェアを追加する順番というのが、実はとても重要です!! これに関しては 公式ドキュメント にも以下のように言及されています。 Program.cs ファイルでミドルウェア コンポーネントを追加する順序は、要求でミドルウェア コンポーネントが呼び出される順序および応答での逆の順序を定義します。 この順序は、セキュリティ、パフォーマンス、および機能にとって重要です。 つまりUseメソッドを呼び出した順にミドルウェアが追加され、その順番に処理も行われます。 上記のProgram.csのコードでリクエストパイプラインの構築を行う場合 ExceptionHandlerのミドルウェアでの前処理を行う ↓ HstsのMidlewareでの前処理を行う ↓ EndpointRoutingミドルウェアでの前処理を行う ↓ ... (略) コントローラでの処理が行われる (略) ... ↓ EndpointRoutingミドルウェアでの後処理を行う ↓ HstsのMidlewareでの後処理を行う ↓ ExceptionHandlerのミドルウェアでの後処理を行う といった順番で処理が行われます。 順番が大切な理由 「順番を誤ると何かまずい事が起こるの?」という問いに対する例を一つ挙げたいと思います。 例えば一番最初に呼ばれているExceptionHandlerのミドルウェアを、リクエストパイプラインの後半で実行するよう変更するとします。 この ExceptionHandler のミドルウェアの役割としては  例外をキャッチし、それらをログに記録し、代替パイプラインで要求を再実行するミドルウェアをパイプラインに追加します。 との記載があります。 つまり、この ミドルウェアがあるからこそ例外がキャッチされログが記録される わけです。 逆に言えば、このミドルウェアが実行される前のソースコードにおいて例外が発生しても、それはログに残りません。 そうするとエラーの解析も難しくなり、障害が起きた時の復旧が困難になってしまいます。 このため、このExceptionHandlerのミドルウェアは一番最初に持ってくる事が大切となります。 他のミドルウェアに関しても同様に、追加する順番には理由があるものが多いです。 そのため 既存のリクエストパイプラインの順番はむやみに変えない 新規にミドルウェアを追加する場合は順番に気を付ける といった心がけが重要になるかと思います。 ターミナルミドルウェア 先ほどまでは Use メソッドを使ってミドルウェアにパイプラインを追加しました。 もう一つ、追加する方法として Run メソッドを利用する方法があります。 注意点として、 Program.csファイルの最後で利用されている app.Run() とは別モノです。 Program.csの最後で利用されているのはApplicationをスタートさせるための Run() であり、 今回紹介するのはMiddlewareを追加するための Runメソッド (拡張メソッド)です。 詳細はリンク先の定義を確認してみてください。 このRunメソッドで追加したミドルウェアは ターミナルミドルウェア(もしくは終端ミドルウェア) と呼ばれるものであり、ターミナルミドルウェアが呼ばれた時点でリクエストパイプラインは終了する形となります。 実際にやってみましょう。 以下のようにターミナルミドルウェアを2つ追加します。 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); //1つ目のターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("1st Hello world."); }); //2つ目のターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("2nd Hello world."); }); app.Run(); この状態でアプリを起動し、以下のURLに遷移します。 Http://localhost:{port}/Home/Index すると、”1st Hello world.”という文字が表示されました。 1つ目のターミナルミドルウェアによってレスポンスが返されていることがわかります。 ただここでふと思ったのですが 今回のサンプルプロジェクトにはControllerコンポーネントに、HomeControllerクラスとIndexメソッドは定義されています。 ターミナルミドルウェアより先にMapControllerRouteによってルーティングが定義されているため リクエストはControllerへとルーティングされ、以下のようなViewが返されるかと思ったのですが、ターミナルミドルウェアの処理が優先されました。 ここの処理がいまいち納得がいっておらず、少し考察してみたいと思います。 考察 ※ここからの記載は真偽の定かではない独自の考察になります まず、上記のProgram.csにおいてMapControllerRouteメソッドによってルーティングが設定されています。 ターミナルミドルウェアである Run() が存在しない場合、このメソッド自体は正しく機能していることは確認できました。 そのため、ルーティングの設定自体は正しく行えているものとします。 ここで、 公式ドキュメント のルーティングに関する記載に以下のような文章がありました。 (翻訳がわかりづらかったので原文で載せます。) Note: Routes added directly to the WebApplication execute at the end of the pipeline. 「WebApplicationインスタンスで直接加えられたルートはPipelineの最後に追加されます」と書かれています。 今回は、この「WebApplicationインスタンスで直接加えられたルート」のケースに該当すると考えます。 また、Runに関する 公式ドキュメント には以下のような記載があります。 Run デリゲートでは、next パラメーターは受け取られません。 最初の Run デリゲートが常に終点となり、パイプラインが終了されます。 そのため、以下の2点から ルーティングはPipelineの最後に追加される Runが呼ばれた時点でPipelineが終了してしまう ルーティングのMiddlewareに到達する前に、RunによってPipelineが終了してしまったのではないかなと考察しました。 回避策 ちなみに以下のような実装をすると、 ルートが存在する場合はControllerの処理が走る ルートが存在しない場合はRunの処理が実行される といった処理を実現できました。 app.UseRouting(); app.UseAuthorization(); //UseEndpointsのミドルウェアを追加 app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); //ターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("Hello world."); }); app.Run(); ちなみに、これは少し前のASP.NET Coreのバージョンでの書き方であり ASP.NET Core 8.0では、 UseEndpoints および UseRouting をわざわざ書かなくていいとされています。(明示的に書く必要がある場合を除き) 実際、UseEndpointsの部分に ASP0014 の警告文も表示されます。 参考: ASP.NET Core でのコントローラー アクションへのルーティング なお、UseEndpointsを利用するとルーティングが正しく行われる理由としては UseEndpointsの 仕様 として、以下の通りであるためです。 一致が見つかると、UseEndpoints ミドルウェアはターミナルです。 ターミナル ミドルウェアについては、この記事で後ほど定義します。 UseEndpoints の後のミドルウェアは、一致が検出されなかった場合にのみ実行されます。 これにより、 UseEndpointsにおいてルートが見つかった場合は、そこでパイプラインが終了しRun()が実行されない UseEndpointsにおいてルートが見つからなった場合は、後続のMiddleware の処理が行われRun()が実行される という処理となると考えられます。 ということで一応回避策はありましたが、MSが推奨する方法ではないですし、あまり納得もいっていないです。 ASP.NET Core2.2時代などはUseMVCの拡張メソッドを利用してミドルウェアを追加した場合 パイプラインの構造が変更され、ターミナルミドルウェアが定義されていても、ルートが一致した場合は無視される動きがありました。 このあたりがASP.NET Core 8.0のMapControllerRouteでは挙動が違うのかなとも予想されます。 MapControllerRouteの挙動などはRoutingの調査の時に改めて行いたいと思います。 今後ASP.NET CoreのRoutingを題材とした記事を書こうと思っているので、その時まで少々お待ちください。 このあたり詳しいよ!わかるよ!という方はぜひぜひコメントお待ちしています。 パイプラインの分岐 RunとUseのほかに Map という拡張メソッドも存在します。 こちらは何かというと、パイプラインの処理をパスによって分岐することが可能となります。 実際にソースコードを修正してみましょう。 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); //分岐1 app.Map("/sios1", HandleMapTest1); //分岐2 app.Map("/sios2", HandleMapTest2); //分岐3(パスに該当しなかった場合) app.Run(async context => { await context.Response.WriteAsync("Hello I am non-Map sios."); }); app.Run(); //分岐1用の処理 static void HandleMapTest1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hi, I am sios1"); }); } //分岐2用の処理 static void HandleMapTest2(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hello, I am sios2"); }); } こちら実行すると、それぞれ分岐した結果のレスポンスが得られました。 分岐なし Http://localhost:{port} 分岐1 Http://localhost:{port}/sios1 分岐2 Http://localhost:{port}/sios2 ただ個人的に「Program.csの可読性が一気に落ちるなぁ」という印象を持ちました。 このMapの拡張メソッドを使用しないと実現できないユースケースを除いては、あまり利用しない方がよいのかなと感じました。 ただ、使いこなせてないだけかもしれないので、気にはかけていこうとは思います。 まとめ 今回はミドルウェアとリクエストパイプラインの概要を説明しました。 ミドルウェアを定義し、それをリクエストパイプラインに追加することでコントローラでの処理の前処理・後処理を実現できることがわかりました。 その際、ミドルウェアを追加する順序も非常に重要であることも気を付けたいポイントです。 ルーティングのところで宿題事項が残ってしまいましたし、パイプラインもまだまだ奥が深いような気がするので、新たな発見があれば追加で記事にしていきたいと思います! ではまた! 参考文献 ASP.NET Core のミドルウェア カスタム ASP.NET Core ミドルウェアを記述する ASP.NET Coreのカスタムミドルウェア ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ASP.NET Core入門 – ミドルウェアとパイプライン 解説【.NET 8】 first appeared on SIOS Tech. Lab .
アバター
PS/SLの佐々木です。 2024/4/13, 14でWEB3/AI SUMMIT2024というイベントがあり参加してきました。 こちらはよくあるカンファレンス形式でテーマは表題通りWeb3関係がメインで、Web3の中でAIをどのように利用していくかというパネルディスカッションが多い印象でした。 こちらのイベントに今回参加してきたので内容を紹介したいと思います。 パネルディスカッションのテーマ 多かったパネルディスカッションのテーマは以下の通りです。 国内のWeb3の取り組み 海外のVCのトレンド Web3とAIの可能性 ステーブルコイン Web3のマスアダプションに向けて必要なもの うまくいっている事例 全体を通して 国内のWeb3の取り組み 日本政府は暗号資産の税率の変化やDAOの法人格化、また会計での課題について現在の進捗と課題を話していました。 先日自民党議員の平さんがWeb3ホワイトペーパーにも出していましたが、2024年に暗号資産の課税方式が期末時価評価課税の対象から除外され、シンガポールやスイスに出て行ってしまった企業家が日本に戻ってきてくれることを期待するといっていました。 またDAOの法人化では現在の合同会社と同等の扱いができるように提言を出すとのことでした。 一方でキャピタルゲインの課税についての議論や暗号資産を寄付した場合などどのような控除が必要なのかといった議論はこれからだとおっしゃられていました。 日本は最初に規制を強め徐々に整備を進めていて、これからな部分は多いものの世界でも進んだ市場を提供していくという力強いメッセージがありました。 日本企業の取り組みとしては大手IT企業では独自でウォレットを開発していたり、NFTを用いたスタンプラリーのようなプロダクトの開発を行っています。 また今後考えていることとしてはIPとコラボした取り組みやコミュニティへの貢献に関するプロダクト、フィールセーフのような仕組み作りを考えているという話がありました。 海外のVCのトレンド 海外のVCトレンドとしてはインフラレイヤーのプロジェクトへの投資が多い印象でした。 様々なL1, L2レイヤーのパブリックチェーンのプロジェクトがありますが、それぞれの相互運用性であったり、Dappsが開発されるにあたってのツールやDeveloperフレンドリーな開発体験を提供するための機能がまだまだ足りておらずこの問題には関心があるようでした。 ブースに出店していた海外のプロジェクトもこれらの問題を解決するためにチェーンから開発してより上位のレイヤーで起きている問題を解決しに行くといったアプローチをとっていることが多い印象でした。 またRWA(Real World Asset)によりコレクションやアンティークの流動性を高めたり、AI関連のプロダクトに関心があるようでした。 Web3とAIの可能性 AIの問題点からそれをWeb3で解決できるというのがセッション全体を通しての流れでした。 AIの問題点は以下の通りです。 データが巨大企業に集まってしまっている 使用されているデータの信憑性 アルゴリズムの不透明さ 結果に対しての検証が困難 企業のさじ加減でAIを使用できなくなる可能性も これらの問題に対してWeb3ではデータやロジックには透明性があり、安全に使用できるのではないかとの見方がされています。 また方法の詳細は分かりませんが、出力の正しさを検証する際にゼロ知識証明を使用することができるのではないかとの意見がありました。 またP2Pの上で構築することで持続可能性も高く、だれもが安価にAIを使用できる未来を示唆している人もいました。 また現在はマシンパワーとデータ量で勝負する(物理で殴るという表現もされますが、、、)世界になってしまっていますが、アルゴリズムとデータがパブリックなものになってくれば誰もがAIを作れる世界線もありえ知恵やアイディアで勝負できるようになるかもしれません。 ステーブルコイン 異なるコイン間のインターオペーラビリティに関する問題と既存のPaymentサービスの差別化(少額決済がやりやすいとか)に関する議論や可能背について語られていましたが、いまひとつステーブルコインが便利な点がわかりませんでした。 国際送金に関しては手数料が安くなる理屈は理解できるのですが、例えばUSDCとJPYCに交換する手順の簡略化など今後行っていかないといけないんだろうと思いました。 Web3マスアダプションに向けて必要なもの まず1点目がWalletについてです。 現在の見立てではユーザーがノンカストディアルウォレットを管理してアプリケーションにアクセスすることは考えにくいとされています。 ウォレットの必要性により現在ユーザーがWeb3アプリケーションに参画しにくくなっている(実際にEmailでログインとWalletログイン両方を備えたサービスでWalletログインを使用したユーザーはいなかった)というのは私自身も感じています。 しかしカストディアルウォレットを使用すると署名用のキーを握られてしまうことになるのでWeb3の理念的には微妙なのかなと思ってたり。 この問題に関しては問題提起のみで解決に関する議論やアイディアはなかったのでチャンスのある領域です。 2点目はチェーン間のインタオペーラビリティです。 現在非常に多くのチェーンがローンチされています。 しかしチェーン間でのデータやトークンのやり取りが非常に難しいという問題があります。 そのためユーザーや開発者はDappsが使用しているチェーンごとにWallet(複数チェーンをサポートしているWalletはありますが、ローンチされているすべてのチェーンに対応することは非常に難しい)を持ち、それぞれのトークンを管理するという煩雑さはユーザーのみならず開発者もやりずらいポイントになっています。 同一チェーンでDappを開発する場合にはチェーン内でのインタオペーラビリティは非常に強みになってくるのですが、様々なチェーンがローンチされている現在はそのメリットが薄まってしまっています。 ここに関しては規格を整備していくのかBridgeするアプリケーションを開発するのか様々なアプローチが考えられるところです。 これらによりユーザーはWeb3に参入しやすくなり、開発者は技術選定がしやすくなったり、Dappの開発が活発になるのではないかと考えられます。 うまくいっている事例 うまくいっている事例ではナイジェリアやアフリカ方面の話があり、自国の政治状態が不安定で自国通貨のボラリティがビットコインのボラリティよりも下回っている場合は資産を暗号資産に移している人が多いようでした。 またアフリカのほうでは銀行口座を持っている人の割合が少なく、また人口も増加しているためマスアダプションに向けてはかなり導入しやすい地域だといわれています。 このようにDefiの分野では導入が進んでいる場所もあるようです。 またチェーンがものすごいTVLをつけているといった話もありましたが、TVLを支えている技術や優位性が今一つまだ理解できておらず、今後個人的な調査課題とさせていただければと思います。 全体を通して 今後の展望や課題は上記で述べた通りで、様々なセッションがありましたが、議題の違いとアプローチの違いはあれどマスアダプションに向けてのボトルネックになっている場所の認識は大方同じように感じました。 個人的にもローンチされているチェーンが多すぎてキャッチアップは追いつかないし、チェーンを変えたくなった場合にどうすればよいかあまりわかっていないので新しいプロダクトの開発状況は今後もウォッチして何か動きがあればこちらで発信していきます。 イベント全体について 今回teamz様か主催しているイベントだったのですが、全体の雰囲気としては日本人と外国人が半分半分ぐらいな印象でした。 また登壇者に関しては2/3ぐらい外国人でほとんどのセッションも英語で行われていました。 しかしたくさんのリアルタイム自動翻訳機があり、精度もそこそこなので英語を聞きながら自動翻訳機を眺めていれば内容は大方問題なく理解できるレベルかと思いました。 またロビーでは朝からお酒やお菓子の提供がされていてDJが爆音で音楽をかけているという日本のイベントではあまり見ない光景で新鮮で非常に楽しかったです。 また私はいろんなブースを回るのが好きなのですが、今回の出展企業やプロジェクトは海外のものが多く(日本人のほうが少なかった)なぜ規制の厳しい日本に来ているのか質問したりプロダクトの説明を受けたりしました。 どうやら規制は厳しいがそれだけ参入障壁が高く、また個人ID(マイナンバー)が普及しきっていないのでチャンスはあると考えているようでした。 またIPが豊富に存在し、日本の規制当局も規制緩和に向けてかなり前向きにとらえていることが非常に好印象のようで、数年前に日本のWeb3企業がシンガポールやスイス拠点でやっているのを横目で見ていたので非常に新鮮な意見でした。 またビットコインの抽選会やハッカソン、VIP専用のエリアやセッションなども新鮮で2日間を通して非常に刺激を受けました。 来年度以降もイベントを開催するようなのでまた是非参加したいと思いました。 イベントロビー 登壇ステージ   協賛企業一覧(日本企業ほとんどない笑)   参考 自民党議員 平将明議員のHPに乗っているWeb3ホワイトペーパーのリンクを張っておきますので興味のある方は読んでみてください! web3ホワイトペーパー2024要旨.pdf web3ホワイトペーパー2024.pdf ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post TEAMZ WEB3 / AI SUMMIT 2024イベントレポート first appeared on SIOS Tech. Lab .
アバター
はじめに こんにちは、サイオステクノロジーの藤井です。経産省が策定した「 ソフトウェア管理に向けたSBOMの導入に関する手引 」という資料の中で紹介されているFOSSologyというSBOMツールについて調査したので、この記事では、その使い方や特徴について解説しています。 SBOMとは SBOMとは、ソフトウェア部品表(Software Bill of Materials)、つまり、ソフトウェアコンポーネントやそれらの依存関係の情報などの一覧のことです。 詳しくは、 SBOM解説記事 を参考にしてみてください。 FOSSologyとは SBOM解説記事内でも紹介した、経産省の「ソフトウェア管理に向けたSBOMの導入に関する手引」の中では、以下の様に紹介されています。 開発元:Linux Foundation OSS の名称やバージョンの特定はできないものの、対象ソフトウェアに含まれるコンポーネントのライセンス及び著作権を検出し、管理することが可能 Web UI を用いたインポートや解析が可能 また、 公式サイト や GitHub では、要約すると以下の様な特徴が挙げられています。 FOSSologyは、ライセンスや著作権などのスキャンが出来るOSSです。 システムとしては、データベース+Web UI の構成です。 ワンクリックで、ソフトウェアのすべての著作権表示を含む SPDX ファイルまたは ReadMe を生成できます。 FOSSologyの導入手順 https://fossology.osuosl.org/ にテストサーバーが立っているので、ちょっと試したいときにはここで出来ます。(毎日データが初期化されます。) 外部に公開したくないコードのスキャンをする場合などは、ローカルにサーバーを構築する必要があります。 インストール 今回は、wsl2でubuntu-22.04を動かし、そこにインストールしました。 wsl2やubuntu-22.04をインストールする手順については、省略します。 公式のインストール手順解説動画があります。( https://www.youtube.com/watch?v=q12KwmPYZG4 ) 情報が古いところが有り、現在とコマンドが異なったりするので、基本的には wiki のコマンドに従う必要がありますが、どのコマンドにsudoが要るかとか、どんなログが出るか、など適宜参考にすると良いと思います。 cloneしてインストール git clone https://github.com/fossology/fossology.git cd fossology/ sudo apt-get update sudo apt install lsb-release sudo ./utils/fo-installdeps --everything ビルド cmake -S. -B./build -G Ninja cmake --build ./build --parallel sudo cmake --install ./build fossyユーザーを作成し、DBをセットアップする sudo /usr/local/lib/fossology/fo-postinstall http://localhost/repo/ にアクセス Username:fossy、password:fossyでログイン スケジューラーの設定 sudo systemctl enable --now fossology sudo systemctl start fossology PHPの設定 sudo ./install/scripts/php-conf-fix.sh --overwrite コードのアップロード 上部メニューのupload > from fileから Upload a New File 画面を開く ファイルを選択し、分析内容を選んでuploadを押す SBOMの生成 上部メニューのBrowseからディレクトリを開く CycloneDX generationボタンでCycloneDXのjsonファイルが、SPDX2 generationボタンでspdxのrdfファイルが生成できます。この例では、CycloneDX形式で出力してみます。 CycloneDXやSPDXについて、詳しくは こちら の記事をご覧ください。 この様に、ファイルごとのライセンスとcopylightの情報を含んだSBOMを生成することが出来ました。 SBOM生成以外の機能 READMEの生成 ReadME_OSS generationボタンで出来ます。Copyrightが羅列されたtxtファイルが作成されました。 ライセンス管理機能 各フォルダを開くと、その中のフォルダやファイルにどんなライセンスのファイルがあるかを確認できます。 また、それぞれのライセンスのファイルが、全体で何個あるのかも確認できます。 個別のファイルを開くと、そのファイルの内容と、そのライセンスが表示されます。自動検出が間違っていた場合は、ここから、削除や編集ができます。 Copyright このソフトウェアに含まれるcopylightの一覧を表示できます。 各項目を選択するとどのファイルにそれぞれのcopylightが記載されているか確認することが出来ます。 API 参考 APIからFOSSologyを操作することもできます。CI/CDなどに組み込む場合に活用できそうです。 まずは、上部メニューのAdmin > Users > Edit User Accountから tokenを取得します。 このtokenをHeaderに`Authorization:Bearer `の形で指定することで、各種操作を行うことが出来ます。 例えば、GET http://localhost/repo/api/v1/foldersで、フォルダーの一覧を取得できます。 利用できるAPIのドキュメントは、openapi定義yamlの形で github上 にあるので、これを swaggerエディター 等で読み込むことで、確認できます。 まとめ 今回は、FOSSologyの特にSBOMツールとしての側面について解説しました。 まとめると、 メイン機能は、コードをスキャンしてライセンスと著作権を自動検出 CycloneDXかSPDX形式のSBOMを生成可能 全部GUIで操作可能+テストサーバー有で、試すハードルは低め こんな感じです。 関連記事 SBOM解説: SBOMのメリットと導入の流れ SBOMツールをカテゴリー分けしてみた SBOMの仕様:CycloneDX(CDX)・SPDX SBOMツール紹介 ~ Dependency-Track編 ~ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SBOMツール紹介 ~ FOSSology編 ~ first appeared on SIOS Tech. Lab .
アバター