ヤフー株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。LINEヤフー Tech Blog

テクノロジー

ヤフーのインターンシップでOSSの機能開発をした話 〜 Apache NiFiのUndo・Redoプロトタイプ開発

はじめまして! 同志社大学理工学部情報システムデザイン学科3年の岩井駿人と申します。

今回私は、ヤフーのデータ統括本部のインターンシップに参加し、Apache NiFiというオープンソースソフトウェア(OSS)に対する、追加機能のプロトタイプを開発しました。本記事では、そのインターンシップの内容について紹介します。

特に、 「ヤフーのインターンシップはどうなのか」、「インターンシップってどんなことをするんだろう」 という疑問を持った、私と同じ学生の方へ向けた内容も書いていきたいと思いますので、ぜひ最後まで読んでいただけると幸いです。

Apache NiFiって?

本題に入る前に、今回使用したApache NiFiについて簡単に説明します。

Apache NiFiとは、システム間でやりとりするデータの送受信を、ブラウザーのUI上で管理できるOSSです。Apache NiFiの特徴として、やりとりするデータの完全性や、操作権限をユーザーごとに変えられることによるセキュリティの機密性などの他に、ブラウザー上で手軽に操作ができる点があります。

ヤフーではApache NiFiをデータ基盤として利活用しています。またヤフーにはコントリビュータも在籍しており、OSSコミュニティへの貢献にも取り組んでいます。Apache NiFiについての詳細は、以下の過去記事をぜひご覧ください。 この記事を書かれた寺田さんは、今回私のインターンシップのメンターをしてくださった方で、より詳細にまとめられています!

インターンシップで行ったこと

Apache NiFi(以降NiFi)というOSSに対して、追加機能のプロトタイプを開発しました。

具体的には、操作を1つ戻す Undo機能 、戻した操作をやり直す Redo機能 を開発しました。WordやExcelなど、みなさんが使うソフトウェアにももちろん搭載されている機能ですが、NiFiにはこの機能が存在しません。その不便さを解消するために、今回の機能追加を行いました!

今回のインターンシップは、フルリモートで2カ月半の間行いました。その2カ月半の記録を順を追って説明します。

1.調査

初めに、今回使用するNiFiの内部プログラムの調査から取り組みました。Undo・Redoのプログラムに関連しそうなソースコードを書き換え、実際にNiFiを動かした時の挙動の変化を調べました。

調査の中で初めに行ったことはシンプルで、UIの文字を変える、というものでした。

UI改変前改変後の比較画像

上の図では、右クリックで出てくるメニューのStartをBeginに変更しています。このような簡単な実装を起点に、徐々にNiFi内部へ踏み込んだ調査をしました。

設計方針の検討

NiFi内部を調査した結果、Undo・Redoの実装のための設計にはいくつかの方法があることがわかりました。Undo・Redoを実装するには、ユーザーの操作時の状態を保持しておく必要がありますが、それを実現するための方法には以下の2つが考えられました。

  • H2データベースを使用する
  • データを保存する処理を作成する

これら2つの方法は、それぞれさらに詳しく調査、および設計を行いました。

実装案1:H2データベースを使用する

NiFiにはH2という内部データベースがあり、そこにユーザーの操作時などの更新情報が記録されています。そして、更新情報を取り出すことによってUndo・Redoを行う方法が考えられました。

しかし、さらに調査を行っていくと、この方法では実現が難しいことを発見しました。それは、NiFiのH2が、メインロジックから切り離されたデータベースであったことです。NiFiのデータベースであるH2はメインロジックと切り離すように設計されており、H2を使ったUndo・Redoの実装にはそれらを跨ぐ必要がありました。

このメインロジックとデータベースを跨いだ実装が難しかったです。また、もともと切り離されたものを再び結びつけるような実装は、プログラムの構造の観点からも良くないでしょう。

よって、最終的にはこのH2を使った実装は断念することにしました。システムの肝となるメインロジックがうまく切り離された構造であることを学び、その反省を生かして次の方法の検討をしました。

実装案2:データを保存する処理を作成する

先ほどのH2を使わない場合、Undo・Redoを実装するための操作履歴を記録する処理を別途用意する必要がありました。そのため、ユーザーの操作でNiFiの内部状況が変化する際に、履歴を保存する処理を作成する方法が考えられました。

内部状態が変化する際に、操作される対象の状態を持つDTOというオブジェクトを生成するため、そのDTOを保存する形で実装することにしました。DTOとは、Data Transfer Objectの略で、データの受け渡し専用のクラスとなっています。そして、ユーザーからUndo(Redo)のリクエストを受け取った際には、対応する操作履歴のDTOを取り出し、それを反映させることで一つ前の状態に戻します。

ただし、NiFiには、複数のユーザーが存在し、またそのユーザーの権限などもバラバラであるため、考慮するべきことは多々あります。しかし、いったん完成を目標に設計を始めました。

2.設計・実装

設計の段階で出た2案は、結果的に実装案2を採用することになりました。さらに具体的にUndo・Redoの設計を考えるにあたって、初めにユーザーの操作がどのように反映されているかを簡単に見てみます。設計を考える際に必要な、NiFiのプログラム上でのコンポーネントが、以下の通りです。

NiFiの構成画像

ユーザーがなんらかの操作を行った際に、NiFi REST APIにリクエストが送られ、NiFiの中のApplication Resourceというオブジェクトが命令を解釈します。そこから内部状態を変化させるNiFi Service Facadeのメソッドが呼び出され、以降NiFi内部が変化していく、といった形です。

NiFi内部の調査に関しては十分行っていたため、この構造から考えられる実装の案は2つありました。それが以下の2つの図です。

Undo設計案2つの比較画像

ここでは、NiFiのプロセッサーを更新する処理を例に挙げています。

この図におけるActionHistoryとは、今回のUndo・Redoの肝となってくる、操作履歴を保持するオブジェクトです。今回は、以下の図のように操作履歴をリスト構造で持つことにしました。ユーザーの操作時にこのオブジェクトで履歴を保存し、Undo・Redo実行時に適切な状態を取り出す、といった仕組みです。

ActionHistoryの概要図

最終的に、2つの案のうち 右側の実装を採用しました。理由としては、Application ResourceとNiFi Service Facadeのそれぞれの役割と関係性を変えるべきではなかったからです。また、Action HistoryがNiFi Service Facadeでしか参照されないため、もともとのプログラム構造をあまり変化させる必要がなく、プログラムの観点からも左側より良いと言えるでしょう。

設計が決まれば、最後に実装に移りました。時間も限られていたこともあり、作成するものに優先度を付け、プログラムを書き始めました。

3.完成したもの

そしてUndo・Redoのプログラムを書き始め、1週間強で完成しました。想定通り正しくUndo・Redoを実行することができ、操作ミスをした際のストレスを少し減らすことができたのではないのでしょうか。

以下のデモ動画で、実際にUndo・Redoの操作した時の挙動を示しています。

完成した際の達成感は大きいもので、素直にとても嬉しかったです。しかし、Undo(Redo)が完全に正しく動いているかの検証をできていない点や、Undo・Redoがまだ実装されていないNiFiコンポーネントが存在する点など、改善点も多々あります。

そのため今後の課題としては、Undo・Redoの完成や検証などがあります。

インターンシップの感想

最後に、インターンシップ全体を通じて感じた感想についてまとめていきたいと思います!特に、今回はフルリモートでの2カ月半程のインターンシップであり、インターンシップ参加前の私も含め、いろいろと気になる部分もあると思うので、長くなりますがたくさん書いていきたいと思います。

リモートでも難なく進めることができた

まず、リモートと聞くと話しづらい雰囲気や時間を持て余す雰囲気がありますが、全くそんなことはありませんでした。チーム内の社員さんの方々とは、「1on1」という1対1でお話しする機会やランチ会を通して、堅苦しくない雰囲気でお話しする機会が多々ありました。また、分からない部分があったらすぐにメンターの方に質問できる環境だったと思います。

他にも、毎日自分に合った量のタスクを割り当ててくださって、ちょうど良いチャレンジをすることができました。その日の小さな目標を作り進めていき、早く終わった際には自分で違う目標を探すことができて、インターンシップ期間を充実して過ごすことができたと思います。

苦労したこと

これに関しては、ヤフーのインターンシップだから、というわけではないのですが、大きなプロジェクトのプログラムの中から必要な部分を読み解く、ということが初めてだったので、それに苦労しました。現にインターンシップ期間の半分以上は、調査に割り当てたことになりますし、本を読むことが嫌いな私にとって大変でした。

しかし、プログラムを書く際に実感しましたが、この調査のおかげで驚くほどスムーズに進めることができました。システム開発やOSS貢献の裏には、地道な努力とドキュメントリーディングが必要なのだと気付かされました…!

学んだこと

このインターンシップを通じて、深く学べたことと幅広く学べたことがどちらもあります。

まず、NiFiという実際に使われている大規模な現行システムの一端に携わることによって、技術的に深く学ぶことができました。NiFiというOSSの構造や仕組み、また大規模システムで使われるデザインパターンなど、限定的な内容ですがソフトウェアエンジニアとして大切なことを学べたと思います。

特にデザインパターンについては、設計案で取り上げたDTOの他にも、データにアクセスするためのDAO(Data Access Object)やDTOを管理するためのFactoryなどもNiFiでは用いられていました。NiFiの調査によって、さまざまなデザインパターンが存在することを知り、同時にそれらを学ぶこともできました。

また、Javaのプロジェクトの構造を読み解くことやそれを改変すること、またそのテストを行うこと、他にも行ったことをドキュメントにまとめることや日報にまとめることなどから、幅広く学ぶことができました。特にソフトウェアエンジニアとして、開発の中で大切なルーティーンを学ぶことができたと思います。

課題・もう少しやりたかったこと

逆にこのインターンシップで浮き彫りになった課題や、もう少しインターンシップでやりたかったこともあります。

まず課題としては、先ほどあげたソフトウェアエンジニアとしてのルーティーンを習慣付けることが挙げられます。自分で目標を決めてそこに向かって努力する、そして完成したら振り返りを行って次につなげる、という経験学習サイクルを日常的に回していく必要性を感じました。

もう少しやりたかったこととしては、Undo・Redoのプログラムの続きです。時間も限られており、できる範囲の完成を目指したため、心残りの部分が多々あります。しかし、これに関しては、どのようなものも理想と現実はあるだろうし、後任される方に向けて引き継ぎのドキュメントの作成などに力を入れたいと感じました。

他にも、OSS貢献としてもう少しこの開発に携わりたかった、という部分もあります。開発したプログラムのドキュメント作成や、プルリクエストの作成など、今回作成したプログラムを実際に使ってもらうための準備があまりできませんでした。しかしこれも、このインターンシップに限らず挑戦できる部分であると思いますので、NiFi以外のOSSでもチャレンジしてみたいと感じました。

最後に

今回のインターンシップを通して、社会での働き方を実感して成長できたとともに、一つの成果を上げることができました。2カ月半と短いようで長い、でもやっぱり短い、といった期間でしたが、自分自身も満足できる結果にすることができて良かったと思います。

そして、私も含め学生のみなさんは、就職活動や進路など考えることはたくさんあると思いますが、この記事が少しでも参考になれば幸いです。

長い記事になってしまいましたが、 最後まで読んでいただきありがとうございました。また、 関わってくださったヤフーの社員の皆様、本当にありがとうございました!

こちらの記事のご感想を聞かせください。

  • 学びがある
  • わかりやすい
  • 新しい視点

ご感想ありがとうございました


岩井 駿人
インターンシップ生
ヤフーのインターンシップに参加しました。猫を飼っているのですが、リモートワークには最適ですね。休憩時間にもふもふしています。

このページの先頭へ