[Cloud] より大きなテントを建てる―クラウドネイティブ、文化と複雑性/Building a Bigger Tent – Cloud Native, Culture, & Complexity

原文はこちら
https://blogs.oracle.com/cloudnative/building-a-bigger-tent-cloud-native-culture-complexity


エンタープライズ企業がクラウドネイティブの文化とオープンソースを取り入れることをお手伝いすること

バルセロナで開かれているKubeCon + CloudNativeCon Europe 2019、Oracleのオープンソースプロジェクトとクラウドサービスは、エンタープライズ企業の開発チームがクラウドネイティブの文化、そしてオープンソースを取り入れることをお手伝いしています。今週もOracle Cloud Infrastructure Service Broker for Kubernetesのリリースとオープンソース化をお知らせしており、Oracleはエンタープライズ企業のワークロードをクラウドに移行するための、オープンソースとクラウドネイティブソリューションへの取り組みを引き続き広げていきます。

この取り組みには、エンタープライズのクラウド移行を容易にするOracleの最近の一連のオープンソースソリューションである、HelidonGraalVMFn ProjectMySQL Operator for Kubernetes、そしてWebLogic Operator for Kubernetesが含まれます。さらに、最近リリースされたOracle Cloud Developer Imageは、Oracle Cloud Infrastructure上での包括的な開発環境――Oracle Linux、Oracle Java SE(Java 8、11、12を含む)、TerraformとさまざまなSDKを含む――を提供します。お客様がクラウドへの移行をできるだけ簡単にするために必要なものがすべて使えることを確実にするために、Oracle Cloud Infrastructureをご利用のお客様はこれらのソフトウェアへのフルサポートを追加コストなしで受けることができます。詳細はこちら
Oracle Cloud Infrastructure Service Brokerによって、お客様はOracleの第二世代クラウドインフラストラクチャサービスにアクセスしたり、それらのライフサイクルをKubernetes API経由でKubernetesの中から管理したりすることができます。特にOracle Databaseを扱う方々にとっては、Oracle Autonomous Databaseクラウドサービスをこの新しいService BrokerとKubernetesを組み合わせて使うことで、クラウドネイティブへの迅速で効率的な道ができたということになります。このユースケースでは、Service Brokerを使用してAutonomous Data WarehouseAutomated Transaction Processingなどのサービスにつなげることで、Kubernetesでアプリケーション基盤すべてのプロビジョニング、設定、管理を自動化します。したがって、データベースを使うアプリケーションをクラウドに移行するだけでなく、同時に生産性を上げ、コストを下げ、アプリケーションアーキテクチャ全体をモダナイズすることができるというわけです。

わたしたちの現状

DevOpsはわたしたちがどのようにソフトウェアを開発したりデプロイしたりするかを変えました。オープンソースは何のプラットフォームを使うかを民主的にしました。そしてクラウドがどこでアプリケーションを開発し、稼動させるかの選択をとても豊かにしました。しかし、現実には多くのエンタープライズ企業の開発チームは取り残されてしまっています――こちらの調査や、こちらの調査でも示されているように、文化の変容、複雑さ、そして学習の課題に直面しているのです。

ソリューション:より大きく、より良いクラウドネイティブのテントを広げる

クラウドネイティブコミュニティはより大きなテント――①よりオープンでマルチクラウドな未来をサポートし、②持続可能で、③すべてのチーム――モダン/トラディショナル、スタートアップ/エンタープライズといったような区別なく――が入れるようなより包括的なもの――を広げる必要があります。それにより、複雑さを増していくのではなく、むしろ減らしていくのです。Oracleはまずはエンタープライズ企業が既に知っているところから始め、慣れ親しんだ場所からクラウドネイティブへの道のりへの橋や入り口を作ることでサポートをします。この戦略はオープンで、持続可能で、包括的なアプローチにフォーカスしています。

オープンソース:エンタープライズ開発者を後押し

Oracleのオープンソースプロジェクトはエンタープライズワークロードをクラウド上に、そしてクラウドネイティブアーキテクチャに移行することを目標としています。Oracle Cloud Infrastructure Service Brokerは、アプリケーションが依存するOracle Cloud InfrastructureのサービスのプロビジョニングとバインディングをKubernetes環境の中から行うことを可能にします。MySQLやVirtualBoxのほかにも、Oracleの最近の主要なオープンソースプロジェクトには以下があります:
  • Helidon: プロジェクトHelidonはKubernetesフレンドリーな、マイクロサービスを開発するためのオープンソースのJavaフレームワークです。
  • GraalVM Enterprise: 最近リリースされたGraalVM Enterpriseは、高パフォーマンスかつ複数言語対応のVirtual Machineです。クラウド環境、ハイブリッド環境でエンタープライズ企業に高い能率、より良い分離性と迅速性をもたらします。
  • Fn: Fnプロジェクトはオンプレミスからパブリック/プライベート/ハイブリッドクラウド環境どこでも動く、オープンソースでコンテナネイティブなサーバレスプラットフォームです。また、サーバレスクラウドサービスであるOracle Cloud Infrastructure Functionsの基盤ともなっています。
  • Grafana PlugIn: Oracle Cloud Infrastructure Data Source for Grafanaは、Grafanaを使用することによりヘルス、キャパシティおよびパフォーマンスのメトリックをクラウドネイティブな方法で監視、また管理できるようにしています。
  • WebLogic Operator for KubernetesWebLogic Server Operator for Kubernetesは既存のWebLogicアプリケーションをKubernetesクラスタ管理へ容易に統合、また、活用することを可能にします。
  • OpenJDK: Javaがオープンであること、その努力のひとつの焦点がOpenJDKです。OpenJDKはオープンソースの協調した努力により現在では6ヶ月の周期でさまざまな新機能がリリースされており、そのうちの多くはJavaをクラウドネイティブデプロイメントに最適化することを狙いとしています。
付け加えると、オープンソースコミュニティへのエンゲージメントはエンタープライズとクラウドに関する既存のプロジェクトを前に進めるに当たり非常に重要です。Oracleは多数のサードパーティのオープンソースプロジェクトへの貢献を続けており、また、Linuxを含む多くのプロジェクトのトップコントリビューターでもあります。

持続可能なクラウドサービス:マネージドかつオープン

この6ヶ月間において、Oracle Cloud Infrastructureでは広い範囲のマネージド・クラウドネイティブサービスをリリースし、またアップデートしてきました。以下にあげるサービスを含むそれらはmエンタープライズ企業が複雑さをスキップし、一足飛びに便利な生産性を享受することを可能にします:
  • Functions - Fnプロジェクトをベースとしている、スケーラブルで、マルチテナントのサーバレスFaaSです。ユーザーに基盤のことを気にすることなく、ビジネス上の要件を満たすためのコードを書くことに集中させてくれます。
  • Resource Manager: マネージドの「Terraform-as-a-Service」(オープンソースのTerraformプロジェクトがベースです)であり、OCIリソース、サービスをプロビジョニングします。
  • Streaming: 継続した、ハイボリュームのデータストリームを取り込み、保持し、リアルタイムに処理するためのマネージドサービスです。
  • Monitoring: ComputeインスタンスやBlock VolumeなどなどのOracle Cloud Infrastructureリソースのためのきめ細かな、すぐに使えるメトリックとダッシュボードを提供します。また、ユーザーは自身のカスタムアプリケーションメトリックを追加することもできます。
  • Container Engine for Kubernetes (OKE): スタンダードなアップストリームKubernetesをベースとし、CNCF準拠の認証を受けたマネージドKubernetesサービスです。

包括的:モダン/トラディショナル、オンプレミス/クラウド

前述したオープンソースソリューションとクラウドネイティブサービスにより、エンタープライズ企業の開発者はクラウドネイティブの文化とオープンソースを取り入れることができるように、また、エンタープライズワークロードのクラウドへの移行を簡単にすることができます。そこにはデータベースアプリケーションチームからJava開発者、WebLogicシステムエンジニア、Go、Python、Ruby、Scala、Kotlin、JavaScript、Node.js開発者などなど、すべてが含まれています。たとえば、Oracle Cloud Developer ImageはOracle LinuxやOracle Java SEサポート、TerraformおよびさまざまなSDKを含む、包括的な開発プラットフォームを提供します。これはOracleのクラウド基盤を使い始める手間を減らすというだけではなく、Oracle Autonomous Databaseをプロビジョンし、稼動させるのを迅速かつ簡単にしてくれます。
KubeConではいつも新しいプロジェクトやエキサイティングな前進を紹介していますが、Oracleは既存のエンタープライズ企業の開発チームがクラウドネイティブの文化とオープンソースを取り入れていくことを助けるために、同じくらいの努力をしています。Oracle Cloud Infrastructure Service Broker for KubernetesやHelidon、GraalVM、Fn Project、MySQL Operator for Kubernetes、 それにWebLogic Operator for Kubernetesなどは、文化の変容と増していく複雑さといったエンタープライズ企業の課題と戦うための大きなテントを建てることをOracleがお手伝いしている方法の、ごく一部でしかないのです。

[Cloud] Service Broker for Kubernetesの提供を開始/Introducing Service Broker for Kubernetes

原文はこちら
https://blogs.oracle.com/cloud-infrastructure/introducing-service-broker-for-kubernetes



Oracle Cloud Infrastructure Service Broker for KubernetesのGeneral Availabilityをお知らせします。DevOpsとKubernetesへの適応を続けていくにあたり、開発者たちは彼らのアプリケーションやマイクロサービスが依存するクラウドサービスのプロビジョニング、およびバインディングを、自動化されたデプロイメントストラテジに含め、能率化することを望んでいます。例えば、あなたのアプリケーションがどこで動くにせよオブジェクトストレージに依存しているとした場合、ストレージ・バケットのプロビジョニングはアプリケーションのデプロイメントプロセスの一部となっているべきです。さらに、できればKubernetesの中のデプロイメントプロセスとしたいところです。


このシンプルで統合されたデプロイメントという構想から、クラウドサービスをアプリケーションおよびそのデプロイツールに対して公開するための一貫性のあるモデルを提供するOpen Service Broker APIプロジェクトが生まれました。この新しいサービスブローカーは、Kubernetesクラスタで、また、Oracle Cloud Infrastructureサービスと組合せて使うためのOpen Service Broker APIの実装です。マイクロサービスやコンテナ化されたアプリケーションのための高いスケーラビリティを持ち、自動化され、自律チューニングするバックエンドであるAutonomous DatabaseなどのOracle Cloud Infrastructureサービスへのアクセスが、このサービスブローカーによってシンプルになります。
OCI Service Broker Architecture

Service Brokerの動作の仕組み

Oracle Cloud Infrastructure Service Broker for KubernetesはHelmチャートとして、Dockerコンテナとして、また、オープンソースとして利用可能です。以下のサービス(今後追加されていきます)へのサービスブローカーアダプタが含まれています:
  • Autonomous Transaction Processing
  • Autonomous Data Warehouse
  • Object Storage
  • Streaming
サービスブローカーをあなたのKubernetesクラスタに追加すると、kubectlの中でOpen Service Broker APIを使って前述のサービスとやり取りできます。これらのサービスをアプリケーションのデプロイ前にあらかじめプロビジョニングしておく必要はありません。アプリケーションを破棄したときにはこれらのサービスを片づけることも忘れないでください。
サービスブローカーはまた、アプリケーションのポータビリティの助けにもなります。一貫性のあるモデルと、クラウドサービスのプロビジョニングのアプリケーションデプロイメントプロセスへの埋め込みとの組合せが意味するのは、あなたが新規クラウド環境にアプリケーションをデプロイする際に、アプリケーション稼働に必要なものが全て揃うということです。開発⇒テスト⇒プロダクションへの進行の際、オンプレミスからクラウドへの移行の際にも同様です。
アプリケーションポータビリティをさらに強化するために、サービスブローカーはクラウドサービスへのサービスバインディングを作成するのにも使うことができます。各バインディングについてサービスブローカーはサービスに接続するために必要になるKubernetesシークレットを作成します。内容、フォーマットは様々で、たとえばObject Storageサービスへのバインディングには、ストレージバケットへアクセスするためのpre-authenticated URI(事前認証済URI)が含まれます。

使ってみよう

ドキュメントを読みソースコードをダウンロードして、Oracle Cloud Infrastructure Service Broker for Kubernetesを使ってみてください。

[Java] Oracle Java SEサポートがOracle Cloud Infrastructureサブスクリプションに含まれるようになりました/Support for Oracle Java SE now Included with Oracle Cloud Infrastructure

原文はこちら
https://blogs.oracle.com/developers/support-for-oracle-java-se-now-included-with-oracle-cloud-infrastructure


Oracle Java――広く利用されており実績のあるJava Development Kit――のサポートが追加コストなしにOracle Cloud Infrastructureのサブスクリプションに含まれることになったことを本日お知らせいたします。このサポートにはOracle Java 8、11と12についての、バグの報告や、定常的な安定性、パフォーマンス、セキュリティアップデートの取得などが含まれていますOracle Javaを利用して、メジャーなパブリッククラウドサービスを含む、あり得る中で最も広いコンピューティングプラットフォームに向けた、ポータブルで高性能なアプリケーションを開発できます。Oracle JavaがOracle Cloud Infrastructureのサブスクリプションの一部となることで、エンタープライズ向けの、また、消費者向けのアプリケーション開発の手間とコストを劇的に削減します。
JavaはNo.1のプログラミング言語であり、また、クラウド開発者たちに最も選ばれている言語でもあるため、このお知らせは重要です。Javaは組み込みアプリケーション、ゲーム、ウェブコンテンツ、そしてエンタープライズソフトウェアで広く使われています。世界中で1200万人の開発者がJavaを使っており、また、Javaのクラウドデプロイメントの選択肢が増えるにつれて使い勝手もさらに増しています。
Oracle Cloud上のOracle Javaは、開発者たちが便利にアップデートにアクセスし、クラウドとOracle Java利用両方についてシングルベンダーからサポートを受けられることで、よりセキュアなアプリケーションを書くことを助けてくれます。しかも追加コストなしの、同じサブスクリプションで、です。さらに、Oracleから署名付きソフトウェア、および最新の安定性アップデート、パフォーマンスアップデート、また、クリティカルな脆弱性を解決するセキュリティアップデートも確実に受け取れます。
Oracle Linux上、またOracle Cloud Infrastructure Virtual MachineとBare Metalインスタンス上の他のOS上でのJavaがこれらのサポートの対象です。Microsoft Windowsはどうかって?もちろん対象です。Ubuntuも含まれるか?YES。Red Hat Enterprise Linuxは?当然YES!

とっても簡単Cloud Developer Image

Oracle Javaのモジュールたちはどうやって取ってくるかって?Oracle Linuxでは、Oracle Cloud Infrastructure yumリポジトリを使用してたやすくインストールできます。しかし、Oracle Cloud MarketplaceにあるOracle Cloud Developer Imageを使うと、使い始めるのはさらに簡単になります。ただクリックするだけで、そのイメージをOracle Cloud Infrastructureコンピュートインスタンスとして起動できてしまうんです。Oracle Cloud Developer Imageは、たとえるなら開発者のための十徳ナイフのようなもので、Oracle Javaをはじめ、あなたが次に進めるプロジェクトでの開発を加速させるいろいろな価値のあるツールをまるっと含んでいます。あなたは数分かそこらでこのイメージをインストールして、準備完了できるというわけです。
Oracle Cloud Developer Imageを使ってみましょう。

[Microservices] Micronaut、GOAMとATPを使ってマイクロサービスを作成/Creating A Microservice With Micronaut, GORM And Oracle ATP

原文はこちら
https://blogs.oracle.com/developers/creating-a-microservice-with-micronaut-gorm-and-oracle-atp

ここ一年の間に、Micronautフレームワークは非常にポピュラーになっています。そしてそれは理由あってのものでしょう。このフレームワークはJVMワールドにとって革命的なもので、コンパイル時の依存性注入、およびReflectionを利用しないAOPを使っています。このことが意味するのは、起動および実行パフォーマンスと、メモリ消費に関して大きな良い効果があるということです。フレームワークはパフォーマンスが良いだけではなく、使いやすくドキュメントもしっかり整備されていなければなりませんが、Micronautはこの両方を満たしています。使っていて楽しく、Groovy、KotlinやGraalVMとの組み合わせで素晴らしい仕事をしてくれます。さらに、Micronautの中のひとたちは、業界が向かっている方向を理解しており、このフレームワークをその方向を意識して作りあげてきました。サーバレスやクラウドデプロイメントに容易にし、それらを助けるような機能を備えています。

このポストでは"Person" APIを公開するマイクロサービスをMicronautを使って作る方法を紹介していきます。このサービスでは、データベース(トラディショナルなRDBMSからMongoDB、Neo4Jなどなどまで)をとても容易に利用することができる「データアクセスツールキット」であるGORMを使用します。具体的に言うと、GORMをOracle Autonomous Transaction Processing DB(ATPデータベース)とやり取りするためのHibernateとして使用します。以下のポイントを見ていきます。
  1. Groovyを使ってMircronautアプリケーションを作成する
  2. そのアプリケーションがGORMを使ってATPデータベースと接続するように設定する
  3. Personモデルを作成する
  4. Personに対してCRUDオペレーションを行うPersonサービスを作成する
  5. Personサービスとやり取りするControlerを作成する
まずはじめに、起動、稼働中であるATPデータベースのインスタンスをお持ちであることを確認してください。幸運なことに、ATPデータベースの構築はとても簡単で、私のボスのGerald Venzlが5分もかからずにATPインスタンスを構築する方法 のポストで説明もしてくれています。稼働中のインスタンスが容易できたら、クライアント証明書ウォレットをコピーしてローカル端末のどこかにunzipしておいてください。
次のステップに進む前に、ATPインスタンスで新しいスキーマを作成し、そこに以下のDDLでひとつテーブルを作成します:
CREATE TABLE person (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
version NUMBER(20) NOT NULL,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NULL,
is_cool NUMBER(1,0) NOT NULL
);
これでMicronautアプリケーションを作成する次のステップの準備ができました。

Micronautアプリケーションの作成

これまでに使ったことがなければ、Micronautをインストールする必要があります。これにはアプリケーション自体やControllerなどの要素を扱いやすくするための便利なCLIも含まれています。インストールできていることを確認したら、以下のコマンドを実行してベーシックなアプリケーションを作成しましょう。
$ mn create-app codes.recursive.gorm.atp.demo --features=groovy
view rawgenerate-app.sh hosted with ❤ by GitHub
ディレクトリの中を一覧し、CLIによって生成されたものを見てみましょう。
見てお分かりのように、CLIによってGradleビルドスクリプト、Dockerfileおよびいくつかの設定ファイルと`src`ディレクトリが作成されています。このディレクトリは以下のようになっています:
この時点で、あなたのお気に入りのIDEにこのアプリケーションをインポートできるようになっているのでインポートしておきましょう。次のステップはCotrollerの生成です:
$ mn create-controller codes.recursive.gorm.atp.controller.Person
view rawcreate-controller.sh hosted with ❤ by GitHub
生成されたControllerに小さな修正を加えます。Controllerを開いて`@CompileStatic`アノテーションを加えましょう。修正イメージは以下です:
package codes.recursive.gorm.atp.controller
import groovy.transform.CompileStatic
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.HttpStatus
@CompileStatic
@Controller("/person")
class PersonController {
@Get("/")
HttpStatus index() {
return HttpStatus.OK
}
}
では`gradle run`(ラッパー経由の/gradlew runでも)を使ってアプリケーションを実行しましょう。アプリケーションが起動すると、ブラウザやcURLコマンドで稼働していることを確認できます。アプリケーションが立ち上がると、コンソールに以下のようなメッセージが表示されます:
10:49:18.118 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 934ms. Server Running: http://localhost:8080
view rawmicronaut-started.sh hosted with ❤ by GitHub
テストしてみましょう:
何もコンテンツは返してきませんが、'200 OK'が見えるのでアプリケーションによってリクエストが受け付けられ、適切にレスポンスを返していることがわかります。
ローカルでのアプリケーションの開発とテストを簡単にするために、わたしは自分のIDE(IntelliJ IDEA)にカスタム実行/デバッグ設定を作成し、カスタムGradleタスクを参照させておきます。あとで結局システムプロパティを渡すことになりますが、これによりIDEから起動したときにそれをやれるようになります。以下のように`build.grade`に新しいタスク`myTask`を作成します:
task myRun(type: JavaExec){
classpath sourceSets.main.runtimeClasspath
main = mainClassName
systemProperties = System.properties
}
view rawbuild.gradle hosted with ❤ by GitHub
ではこのタスクを参照するカスタム実行/デバッグ設定を作成し、のちほどOracle DB接続に必要となるVMオプションを追加しておきましょう:
コピペ用に追加が必要なプロパティを置いときます:
-Doracle.net.tns_admin="/path/to/atp/wallet"
-Djavax.net.ssl.trustStore="/path/to/atp/wallet/truststore.jks"
-Djavax.net.ssl.trustStorePassword="[wallet truststore password]"
-Djavax.net.ssl.keyStore="/path/to/atp/wallet/keystore.jks"
-Djavax.net.ssl.keyStorePassword="[wallet keystore password]"
-Doracle.net.ssl_server_dn_match=true
-Doracle.net.ssl_version="1.2"
-DdataSource.username=user
-DdataSource.password=L33THax0r!!!!~@@~
view rawvm-options.txt hosted with ❤ by GitHub
次のステップに進んでアプリケーションがATPとおしゃべりできるようにしましょう!

アプリケーションのGORMとATP用の設定

アプリケーションを設定する前にOracle JDBCドライバがあることを確認しておきましょう。ダウンロードし、アプリケーションのルートに`libs`というディレクトリを作成して配置しましょう。以下のJARが`libs`ディレクトリにあることを確認してください:
`build.gradle`の`dependencies`ブロックを修正し、Oracle JDB JARと`micronaut-hibernate-gorm`アーティファクトを依存に含めておいてください:
dependencies {
compile 'io.micronaut.configuration:micronaut-hibernate-gorm'
implementation fileTree(dir: 'libs', include: ['*.jar'])
compile "io.micronaut:micronaut-http-client"
compile "io.micronaut:micronaut-http-server-netty"
compile "io.micronaut:micronaut-runtime-groovy"
compile "io.micronaut:micronaut-validation"
compileOnly "io.micronaut:micronaut-inject-groovy"
runtime "ch.qos.logback:logback-classic:1.2.3"
testAnnotationProcessor "io.micronaut:micronaut-inject-java"
testCompile "org.junit.jupiter:junit-jupiter-api"
testCompile "io.micronaut.test:micronaut-test-junit5"
testCompile("org.spockframework:spock-core") {
exclude group: "org.codehaus.groovy", module: "groovy-all"
}
testCompile "io.micronaut:micronaut-inject-groovy"
testCompile "io.micronaut.test:micronaut-test-spock:1.0.1"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
}
view rawbuild.gradle hosted with ❤ by GitHub
`src/main/resources/application.yml`にあるファイルを修正し、データソースとHibernateを設定しましょう:
micronaut:
application:
name: demo
dataSource:
pooled: true
dbCreate: validate
url: jdbc:oracle:thin:@barnevents_low?TNS_ADMIN=/path/to/atp/wallet
driverClassName: oracle.jdbc.driver.OracleDriver
hibernate:
dialect: org.hibernate.dialect.Oracle12cDialect
cache:
queries: false
use_second_level_cache: false
use_query_cache: false
region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
view rawapplication.yml hosted with ❤ by GitHub
これでアプリケーションがGORM経由でATPとやり取りすることができるようになったので、サービス、モデルといくつかのControllerメソッドを作成していきましょう!まずはモデルから始めます。

モデルの作成

GORMモデルを使うのはすごく簡単です。それはモデルエンティティであることを示し、Bean Validation APIでバリデーションをさせるための特別なアノテーションが追加されただけのPOGO(Plain Old Groovy Object)です。ここから'Person.groovy'というGroovyクラスを`model`という新ディレクトリに作成することで、`Person`モデルオブジェクトを作成していきましょう。以下のようにモデルを作ってください:
package codes.recursive.gorm.atp.model
import grails.gorm.annotation.Entity
import groovy.transform.CompileStatic
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size
@CompileStatic
@Entity
class Person {
@NotNull
@Size(min=5, max=50)
String firstName
@Size(min=5, max=50)
String lastName
@NotNull
Boolean isCool = false
}
view rawPerson.groovy hosted with ❤ by GitHub
ここでいくつかのアイテムに注目してみましょう。クラスに@Entity(`grails.gorm.annotation.Entity`)のアノテーションを付けたので、GORMはこのクラスを管理対象であると知ることができます。われわれのモデルは3つのプロパティ、firstName、lastNameとisCoolを持っています。`person`テーブルを作った際に使ったDDLを見返すと、モデルに結び付けられていないふたつのカラム、IDとversionがあることに気づくでしょう。IDカラムはGORMエンティティで暗黙に用いられ、versionカラムもエンティティの楽観的ロックを扱うためにGORMに自動的に管理されます。また、のちに見ていくことになるいくつかのデータバリデーションに用いるプロパティのアノテーションも登場します。
ここでもういちどアプリケーションを起動するとGORMがエンティティを特定してMicronautがHibernateの設定をしているのを見ることができます:
次はサービスの作成を行っていきます。

サービスの作成

わたしは嘘は言いませんよ。もしあなたがステップが難しくなっていることを待っているなら、そんなことにはならないと言っておきましょう。`Person` CRUDオペレーションを管理するためのサービスの作成は、本当に簡単です。`PersonService`というGroovyクラスを`service`という新ディレクトリに作成し、以下のように記述しましょう:
package codes.recursive.gorm.atp.service
import codes.recursive.gorm.atp.model.Person
import grails.gorm.services.Service
import groovy.transform.CompileStatic
import javax.validation.constraints.NotNull
@CompileStatic
@Service(Person)
abstract class PersonService {
abstract int count()
abstract List<Person> findAll()
abstract List<Person> findAll(Map args)
abstract Person find(@NotNull Long id)
abstract Person save(Person person)
abstract Person delete(@NotNull Long id)
}
view rawPersonService.groovy hosted with ❤ by GitHub
実際のところこれだけです。これでこのサービスはControllerから渡されたオペレーションを扱うことができます。GORMは十分にスマートなので、ここで渡したメソッドシグネチャを受け取ってメソッドを実装してくれます。abstractクラスアプローチ(interfaceアプローチではなく)を使うののいいところは、追加でメソッドの実装が必要となるビジネスロジックがあれば自分でメソッドを実装することができる点です。
まだ目に見えるような変更を加えてないので、ここでアプリケーションを再起動する必要はありません。次でControllerを修正することで変更が目に見えるようになります。

Controllerの作成

前のステップで作成した`PersonController`を修正して永続化オペレーションを行うために使うエンドポイントを追加しましょう。まず、PersonServiceをこのControllerにinjectする必要があります。これもまた簡潔でおこなうことができ、以下をクラス宣言部に追加するだけです。
@Inject PersonService personService
このControllerの中で最初にやっておくべきなのは`Person`の保存メソッドです。このための`@Post`とアノテーションをつけたメソッドを追加し、このメソッドの中で`PersonService.save()` メソッドを呼び出させます。うまくいった場合には新規に作成した`Person`を返却し、うまくいかなかった場合にはバリデーションエラーのリストを返却します。MicronautはHTTPリクエストのボディをControllerメソッドの`person`引数にバインドするので、このメソッドの中では完全に埋められた`Person`ビーンを取得できる点に留意してください。
@Post("/save")
HttpResponse<Map> savePerson(@Body Person person) {
try {
return HttpResponse.ok( [ person: personService.save(person) ] as Map )
}
catch(ValidationException e) {
return HttpResponse.unprocessableEntity().body(
[
person: person,
errors: e.errors.allErrors.collect {
FieldError err = it as FieldError
[
field: err.field,
rejectedValue: err.rejectedValue,
message: err.defaultMessage
]
}
]
) as HttpResponse<Map>
}
}
これでアプリケーションを起動すると、`/person/save/`エンドポイントを用いて`Person`を永続化できるようになりました:
200 OKレスポンスとともに`Person`を格納したオブジェクトが返却されていることに注目ください。しかし、不適格なデータを用いてオペレーションを試してみると、エラーが返却されることになります:
われわれのモデルでは`Person`firstNameは(とても妙な話ではありますが)5~50文字でなければならないと指定していたため、バリデーションエラーの配列を格納した422 Unprocessable Entityがレスポンスと返されてきます。
ここで、ATPインスタンスの中に格納されているすべてのPersonオブジェクトをクエリするために使う`/list`エンドポイントを追加していきましょう。ページネーションに使うためのふたつのオプショナルな引数も設定しておきます。
@Get("/list{/offset}{/max}")
List<Person> getPersons(@Nullable Optional<Integer> offset, @Nullable Optional<Integer> max) {
if( offset && max ) {
return personService.findAll([offset: offset.get(), max: max.get()])
}
else {
return personService.findAll()
}
}
Remember that our `PersonService` had two signatures for the `findAll` method - one that accepted no parameters and another that accepted a `Map`.  The Map signature can be used to pass additional parameters like those used for pagination.  So calling `/person/list` without any parameters will give us all `Person` objects:
`PersonService`には`findAll`メソッドとしてふたつのシグネチャを持っていることを思い出してください――ひとつはパラメータを受け付けておらず、もうひとつはMapを受け付けるものです。Mapシグネチャはページネーションに使うもののような追加の引数を渡すのに使えます。ということで、パラメータなしで`/person/list`を呼び出すと、全ての`Person`オブジェクトを返してくれます:
あるいはページネーションパラメータを使うとサブセットが取れます:
また、IDで`Person`を取得するための`/person/get`エンドポイントも追加しておきましょう:
@Get("/get/{id}")
Person getPerson(int id) {
return personService.find(id)
}
`Person`を削除するための`/person/delete`エンドポイントも追加しましょう:
@Delete("/delete/{id}")
HttpResponse<Map> deletePerson(Long id) {
try {
return HttpResponse.ok( [person: personService.delete(id), deleted: true] as Map )
}
catch(e) {
return HttpResponse.unprocessableEntity().body(
[
message: "Could not delete person with ID: ${id}"
]
) as HttpResponse<Map>
}
}

まとめ

Micronautがパフォーマンスの高いマイクロサービスアプリケーションを作成する際のシンプルでありながらパワフルなやり方であること、また、Hibernate/GORMを用いてのOracle ATPバックエンドへのデータ永続化が簡単に実現できることがおわかりいただけたかと思います。
ここで紹介したアプリケーションの全体を見たい場合はGithubで見るかクローンしてくださいね。