[Linux] Announcing Oracle Linux 7 Update 6 Developer Preview

原文はこちら。
https://blogs.oracle.com/linux/announcing-oracle-linux-7-update-6-developer-preview

Oracle Linuxを開発用のディストリビューションを作成するという実行中の目的の一環で、Oracle Linux 7 Update 6の開発者プレビューの提供を発表でき、うれしく思っています。

Oracle Linux 7 Update 6 Developer Previewには以下のカーネルパッケージが含まれています。
Unbreakable Enterprise Kernel Release 5(デフォルトのカーネル)
kernel-uek-4.14.35-1818.2.1.el7uek.x86_64
最新のRed Hat Compatible Kernel (RHCK、Red Hat互換カーネル)
kernel-3.10.0-933.el7.x86_64
To get started with Oracle Linux 7 Update 6開発者プレビューを試すには、Oracle Technology Networkからダウンロード可能なISOイメージを使ってフレッシュインストールすればOKです。
Developer Preview for Oracle Linux 7
https://www.oracle.com/technetwork/server-storage/linux/downloads/linux-beta-4409163.html
もしくは、既存のOracle Linux 7のインストール環境をアップデートすることでも可能です。この場合、Oracle Linux yumサーバもしくはUnbreakable Linux Network(ULN)のOracle Linux 7 Update 6用開発者プレビューチャネルを使ってください。
Oracle Linux Yum Server
https://yum.oracle.com/
Unbreakable Linux Network
https://linux.oracle.com/
# vi /etc/yum.repos.d/public-yum-ol7.repo

[ol7_u6_developer]
name=Oracle Linux $releasever Update 6 installation media copy ($basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL7/6/developer/$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
enabled=1

[ol7_u6_developer_optional]
name=Oracle Linux $releasever Update 6 optional packages ($basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL7/optional/developer/$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
enabled=1
Oracle LinuxのyumサーバはOracle Cloud Infrastructure内でミラーリングされており、高速にダウンロードできるようになっています。手順に従ってOracle Cloud InfrastructureのOracle Linux Yumサーバのミラーを構成できます。
Oracle Cloud Infrastructure - IaaS
https://cloud.oracle.com/en_US/iaas
Connecting to Oracle Linux yum server mirrors in Oracle Cloud Infrastructure (OCI)
http://yum.oracle.com/getting-started.html#OCIYumMirrors
yumチャネルの設定を変更し、Oracle Linux 7 Update 6開発者プレビューチャネルを有効化し、アップグレードを実行します。
# yum update
アップグレード完了後、システムを再起動すれば、Oracle Linux 7 Update 6開発者プレビューが動作するでしょう。
# cat /etc/oracle-release
Oracle Linux Server release 7.6
このリリースは開発およびテスト目的で提供されるものであり、Oracle Linuxサポートの範囲外です。Oracleはこのプレビューリリースを本番環境に利用することを推奨しません。

ご質問がある方は、Oracle LinuxCommunityのOracle Linux and UEK Preview spaceをチェックしてください。
Oracle Linux and UEK Preview
https://community.oracle.com/community/server_&_storage_systems/linux/oracle_linux_and_uek_preview
Oracle Community - Linux
https://community.oracle.com/community/server_&_storage_systems/linux
もしOracle OpenWorldにお越しになって、Oracle Linuxや仮想化について詳しく知りたい、製品エキスパートと会話したい方は、Moscone SouthのOracle Infrastructure Technologiesショーケースの#120ブースにお立ち寄りください。会場右側のAutonomous Databaseショーケースの目の前にあります。

[Java] The OpenJDK Community TCK License Agreement (OCTLA)

原文はこちら。
https://blogs.oracle.com/java-platform-group/the-openjdk-community-tck-license-agreement-octla

2006年にJava SE Platformのオープンソース実装を共同作業する場所としてOpenJDK Communityを立ち上げた後、次の作業はJava SE TCK(JCK)をOpenJDK Communityに関わり、OpenJDKに貢献している人たちが利用できるようにすることでした。
OpenJDK Community
http://openjdk.java.net/
Sun Microsystemsは、OpenJDK Community TCK License Agreement(OCTLA)を通じてこれを実現しました。このAgreementは2007年に利用可能になり、2008年には動作保証済みのビルドが現れました。OracleはJava SE 7用のOCTLA、Java SE 8用のOCTLA、そして新しいリリース・サイクルでは、Java SE 9以降で一つにまとめたAgreementをリリースし、このプログラムを継続、拡張しました。
OpenJDK Legal Documents
http://openjdk.java.net/legal/
Sun Fulfills Promise of Open and Free Java Technology and Releases Java SE Platform to OpenJDK Community
https://tech-insider.org/java/research/2007/0508.html
OpenJDK & IcedTea
https://rvokal.fedorapeople.org/devconf/OpenJDK.pdf
OPENJDK COMMUNITY TCK AND EA TCK LICENSE AGREEMENT V 3.0
http://openjdk.java.net/legal/OCTLA-JDK9+.pdf
複数のJava SEのバージョンで数多くの署名を頂いています。
OCTLA Signatories List
http://openjdk.java.net/groups/conformance/JckAccess/jck-access.html
最初のOCTLA FAQはまだ以下のURLでご覧いただけます。
TCK
https://web.archive.org/web/20080308193310/http:/www.sun.com:80/software/opensource/java/faq.jsp#k
Oracleは、もともと考えられていたように、OCTLAプログラムの伝統と意図を引き続き適用してきました。つまり、OCTLAはOpenJDKコミュニティに関わり、貢献している個人や組織を対象とし、OpenJDKコードのGPLライセンスでのみ配布される、これらの個人や組織による実装をテストします。FAQに記載の通り、OCTLAは「Javaテクノロジ標準の独立した実装」ではありません。独立した実装では、Oracleは商用のJCKオプションを提供しており、これによってJavaの開発全体に資金を提供しています。実際、OpenJDKコミュニティに参加している多くのOCTLA署名者は、独立した実装(非OpenJDK)ベースの製品とサービスのための商用JCK契約も締結しています。Javaテクノロジー標準の独立した実装の例として、BEA JRockitやIBM J9などがあります。
BEA JRockit
https://web.archive.org/web/20061017075042/http:/www.bea.com/framework.jsp?CNT=index.htm&FP=/content/products/jrockit/
IBM developer kits
https://www.ibm.com/developerworks/java/jdk/
Oracleは、OpenJDK Communityの利益のために、この長年にわたるプログラムの精神と意向を一貫して実施しており、Sunの買収後もプログラムを継続する予定です。

[Java] Updates to the Java SE Platform

原文はこちら。
https://blogs.oracle.com/java/java-se-releases

OpenJDKはGPLv2+CEのライセンスでJava Development Kit version 11の本番利用可能なオープンソースビルドを提供します。
OpenJDK 11.0.1 (built by Oracle)
https://jdk.java.net/11/
JDK 11.0.1 Release Notes
https://jdk.java.net/11/release-notes
GNU General Public License, version 2, with the Classpath Exception
http://openjdk.java.net/legal/gplv2+ce.html
Java SE 11.0.1はJava SE Platformの最新のアップデートです。
Java SE at a Glance
http://www.oracle.com/technetwork/java/javase/overview/index.html
Java SE 11はJava SE Platformの最初の長期サポート機能リリース(Long Term Support feature release)です。
Java SE 11.0.1 release notes
https://www.oracle.com/technetwork/java/javase/documentation/11u-relnotes-5093844.html
Java SE 11.0.1 (LTS) download
http://www.oracle.com/technetwork/java/javase/downloads/index.html 
Java SE 8u191 (Java SE 8 update 191) と Java SE 8u192 (Java SE 8 update 192) がご利用いただけるようになっています。
Java SE 8u191/192
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
最新のJava 8アップデートには重要なセキュリティに関する脆弱性の修正が入っているため、ほとんどのJava SE 8をご利用のお客様に対し、現在利用中のJava 8のアップデートされることをOracleは強く推奨します。2019年1月のアップデートを過ぎてからは、Oracleは商用利用向けのJava SE 8のアップデートをパブリックダウンロードサイトに掲載いたしません。このリリースに含まれる新機能やバグ修正の情報は、以下のリリースノートをご覧ください。
Java Development Kit 8 Update Release Notes
http://www.oracle.com/technetwork/java/javase/8u-relnotes-2225394.html
Oracle Java SE Embedded Version 8 Update 192もご利用いただけるようになっています。
Oracle Java SE Embedded Downloads
http://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/index.html
JRECreateツールを使ってカスタマイズしたJREを作成できますが、そのためには、稼働対象のプラットフォームに適したeJDKバンドルをダウンロードして、以下の手順に従い、アプリケーションの要求事項に適うJREを作成してください。
Oracle® Java SE Embedded Developer's Guide Release 8
Create Your JRE with jrecreate
http://docs.oracle.com/javase/8/embedded/develop-apps-platforms/jrecreate.htm#JEMAG270
Oracle Java SE 8 EmbeddedはOracle Java SE Embedded製品の最後のメジャーリリースで、JDK 9からは、Oracleは個別のJava SE Embedded製品のダウンロードを提供する予定はありません。
また、Java SE 7u201とJava SE 6u211もリリースされていますが、これらは両方ともOracle Java SE Supportの一環でご利用いただけます。これらのリリースに関する詳細は、以下のリリースノートをご覧ください。
Java SE 7 Advanced and Java SE 7 Support (formerly known as Java for Business 7) Release Notes
http://www.oracle.com/technetwork/java/javaseproducts/documentation/javase7supportreleasenotes-1601161.html
Java SE 6 Advanced and Java SE 6 Support (formerly known as Java SE for Business 6) Release Notes
http://www.oracle.com/technetwork/java/javase/overview-156328.html

[Java] Moving Forward with Eclipse GlassFish at Jakarta EE

原文はこちら。
https://blogs.oracle.com/theaquarium/moving-forward-with-eclipse-glassfish-at-jakarta-ee

Jakarta EEに関する直近のエントリで、Java EEテクノロジのJakarta EEへの移行は大きな取り組みであるとお伝えしました。
The road to Jakarta EE
https://blogs.oracle.com/theaquarium/the-road-to-jakarta-ee
https://orablogs-jp.blogspot.com/2018/04/the-road-to-jakarta-ee.html
Jakarta EE
https://jakarta.ee/
過去数ヶ月の進捗はすばらしいもので、Oracle GlassFishの全ソースコードだけでなく、Java EE Technology Compatibility Kits(技術互換性キット、TCKs)のソースコードもJakarta EEに寄贈しました。プロセスのこの段階の完了は、Jakarta EEイニシアチブにとっての重要なマイルストンになりました。そのため、時間をとって現在の状況ならびにこれまでに実施したことを振り返ることにしました。

このソフトウェアに貢献しているのには数多くの理由があります。まず、Jakarta EEが任意の1ベンダーが管理するのではなくコミュニティ管理の下進化してもらいたいためです。Oracle GlassFishとそのコンポーネントをEclipseプロジェクトに移行することで、これらのテクノロジがベンダーニュートラルな形で進化できます。2つめの理由は、Jakarta EEを一連の標準かつブランドとして確立し、互換性の目標を果たす実際の実装が複数あることを実証したいと思っているからです。Eclipse GlassFishはOracle GlassFishのソースコードをEclipse Foundationに寄贈したものでできていますが、これはJakarta EEの参照実装(Reference Implementation、RI)にはならず(参照実装は1個だけではない予定です)、最初のJakarta EE実装の一つになりそうで、このことはJakarta EEテクノロジがJava EEと互換性があるという具体的な実証になることでしょう。最後は、Jakarta EE実装のための明確なセット互換性テストの確立を意図しているからです。何年間もJaav EE互換性を確立するために使用されてきたJava EE互換性テストの最新版であるJava EE 8 TCKsを開始点にするのが最善であると考えました。これらのTCKの寄贈の結果、Jakarta EEでは、Jakarta EE 8の最初の互換性テストをすぐに定義し、TCKソースを進化させることで標準の進化の進展につれてこれらのテストも進化させることができます。

これらのソースを提供するために、まずOracleはOracle GlassFish 5.0のソースコード全てを一連のコンポーネントに編成して、EE4Jプロジェクトの傘の下にある具体的なEclipseプロジェクトにマッピングしました。
Eclipse EE4J
https://projects.eclipse.org/projects/ee4j
39個のEE4Jプロジェクトがあり、この中にはJersey、JAX-RS、Mojarra、JSON-P、TCKsのプロジェクト、そしてGlassFishに含まれなかった新しいJakarta EEテクノロジであるKrazo MVCプロジェクトなどがあります。これらのプロジェクトのそれぞれについて、寄贈したソースをホストするためにEclipseで一連のGitHubリポジトリを作成しました。Oracleは、Oracle GlassFishのソースおよび関連するライセンスを確認し、Eclipse Foundationによるソースのレビューを含む、寄贈の準備ができていることを確認し、寄贈のためのEclipseでのプロセスを進めました。寄贈プロセスによるこのレビューが完了すると、対応するGitHubリポジトリに公開されました。状況のサマリページでは、Jakarta EE仕様でホストされる予定のKrazoとPlatformプロジェクトを除いたすべてのプロジェクトリポジトリへの寄贈(の状況)を公開してきました。
EE4J Project Bootstrapping
https://www.eclipse.org/ee4j/status.php
この結果、Eclipse FoundationでホストされているJakarta EEの実装に使用できるオープンソースができあがりました。これらのプロジェクトの中には、すでにEclipseのリリースレビュープロセスを完了しているものがあります。
Release Review
https://www.eclipse.org/projects/handbook/#release-review

これらのソースを使用してEclipse GlassFishビルドの作成を開始しており、nightly buildをポストし、ダウンロードできるようにする予定です。Java EE 8互換のEclipse GlassFishのリリースを作成する目的で、これらの夜間ビルドに対してJava EE 8 TCKを実行します。以下のURLにあるスケジュールに従ってこのプロセスを完了したいと考えています。
[ee4j-pmc] ACTION: Eclipse GlassFish release plan
https://www.eclipse.org/lists/ee4j-pmc/msg00951.html
お手伝い頂けるのであれば、プロジェクトリーダーに連絡してEE4Jのコミッターになってください。

EclipseCon EuropeとOracle Code Oneで詳しく知って頂けます。EclipseCon EuropeのCloud Native Javaトラックと、Oracle Code OneのJava Server-Side Development and MicroservicesトラックのJakarta EEセッションをご覧ください。
Cloud Native Java - EclipseCon Europe 2018
https://www.eclipsecon.org/europe2018/session-tracks-eclipsecon-europe-2018/cloud-native-java
Java Server-Side Development and Microservices - Oracle Code One 2018
https://oracle.rainfocus.com/widget/oracle/oow18/catalogcodeone18?search.codeonetracks=1522259325398010dTIU&search=jakarta%20ee
どちらかのコンファレンスでお会いできればと思っています。

[Cloud] Fn Hot Docker Functions

原文はこちら。
https://medium.com/fnproject/fn-hot-docker-functions-e02d15033392

理想的には、Fn functionは「ホット」(Cold Startが不要ですぐに動き出せる状態)であるべきです。
Fn Project
http://fnproject.io/
hot functionであれば、関数コンテナの始動後生存し続けて、一連の関数呼び出しを処理しようとします。hot functionがすばらしいのは、コンテナ始動のコストが大きいからです。Fnサーバーは、イメージがローカルにキャッシュされていない場合はリポジトリからイメージをプルし、コンテナを起動し、通常はコンテナ内で言語ランタイムをブートしてから関数呼び出しの処理を開始します。hot functionを使用すると、これらの「コールドスタート」(プル/スタート/ブート)のコストは最初の起動時に支払うだけですみます。後続の呼び出しでのレイテンシは劇的に少なくなります。だから、自然とhot functionを常にデプロイすべきと考えますよね。残念ながら、functionとしてDockerコンテナをデプロイする場合はそれほど簡単ではありませんが、手はあります。

Fn Function Development Kits(FDKs)を使用している場合、hot functionは簡単です。 実際には、おそらくFDKを使用していて、あなたのfunctionがhotかどうかに考えが及んでいなかったかと思います。アプリケーションにFDKライブラリを含め、ハンドラfunction(またはメソッド)を書き、ハンドラをFDKに渡しました。 コンテナが生きている状態で、FDKが関数の呼び出しをリッスンするリクエスト・ループを提供しているという事実はですが、実のところそうなっています。

FDKを使っていない場合、functionをデフォルト(つまりhotではない)コンテナ・コントラクトで実行しています。デフォルトの場合、コンテナは各functionの呼び出しで開始され、入力を標準入力(stdin)でコンテナに渡し、レスポンスを標準出力(stdout)から読み取り、その後シャットダウンされます。動作しますが、hot functionの低レイテンシでのレスポンスは提供しません。


Hot Docker

FDKによる人気のある言語のサポートに加え、FnはfunctionとしてDockerコンテナのデプロイをサポートします。これは他の多くのFunction-as-a-Serviceプラットフォームと比較した場合の大きな差別化要因です。Fnでは、コンテナがサポートされているコンテナ・コントラクトのいずれかを実装している限り、functionとして任意のものをデプロイできます。幸いにも、デフォルトのstdin/stdoutコンテナ・コントラクトをカスタムのコンテナ化されたfunctionに簡単に組み入れることができます。たとえば、コンテナイメージとしてNode.jsプログラムをパッケージ化するDockerfileがあるとします。これをfunctionとしてFnにデプロイできます。

(注意)この例は説明目的にすぎません。実際には、最適なNode.jsのパフォーマンスのためにはFn Node FDKを使うべきです(訳注:2018/10/10現在Experimentalのようです)。
Experimental FDK for Node.js
https://github.com/fnproject/fdk-node
func.js
name = "World";
fs = require('fs');
try {
  input = fs.readFileSync('/dev/stdin').toString();
  if (input) {
    name = input;
  }
} catch(e) {}
console.log("Hello", name, "from Node!");
Node.js default container contract Dockerfile
FROM node:8-alpine

WORKDIR /function

ADD func.js /function/func.js

ENTRYPOINT ["node", "./func.js"]
func.yaml ファイルとfn buildで、このfunctionをビルドできますが、(コンテナ・コントラクト)formatdefaultruntimejavanodeといったFnでサポートされている言語ではなく、dockerを設定することに注意してください。
default docker func.yaml
schema_version: 20180708
name: hello
version: 0.0.1
runtime: docker
format: default
これらの3ファイルを使い、デフォルトのコンテナ・コントラクトのfunctionをデプロイできるのですが、このfunctionはhot functionの場合に比べてレイテンシが小さくなりません。というのも、各呼び出しで、コンテナとNode.jsランタイムの起動コストが必要だからです。ローカルのFnサーバーにデプロイしてこのfunctionをtimeコマンドを付けて起動すると、約1.3秒のレスポンス時間があることがわかります。かなり悪い結果ですが、MacBook上でDockerコンテナを起動しているので、これぐらいの時間がかかるのも無理はありません。

“Hotwrap” Prototype

このコードをhot functionとして実行できれば、ずっといいですね。幸運なことに、FDKを使わないfunctionをhot functionとして簡単にデプロイするために、 コードネーム "hotwrap" というプロトタイプユーティリティを現在開発しています。
hotwrap - Command wrapper that lets you run unix commands as functions
https://github.com/fnproject/hotwrap
Hotwrapはhot functionのコンテナ・コントラクトを実装し、functionが呼び出されるたびに標準入出力ベースのfunctionを実行します。Hotwrapを使用すればfunctionコンテナは生存し続けるので、コンテナの起動コストを回避できます。ただし、各呼び出しで実行可能なfunctionを起動するためのコストはかかります。

hotwrapを使うには、コンテナのENTRYPOINTとしてhotwrapを実行可能にして、実行可能なfunctionを起動するためにCMDを設定するだけです。以下のDockerfileは、先述のNode.jsのサンプルコードに対してhotwrapを追加するために必要な変更を加えたものです。

(注意)この例はマルチステージDocker buildを使ってDockerイメージから実行可能なhotwrapを取得していますが、このイメージはまだDocker Hubには公開されていません。このイメージをGitHubに上がっているソースからビルドできます。
Dockerfile with hotwrap
# Pull the hotwrap container  as a build dependency
FROM fnproject/hotwrap:latest as hotwrap

# Start of your normal docker file
FROM node:8-alpine

WORKDIR /function

# Add function implementation
ADD func.js /function/func.js
CMD node ./func.js

# Install hotwrap binary in your container
COPY --from=hotwrap /hotwrap /hotwrap
ENTRYPOINT ["/hotwrap"]
アップデートしたDockerファイルを使って、Node.jsのfunctionを再デプロイして、再度timeコマンドを使って計測します。最初の呼び出しでは、functionの実行に0.775秒要しました。この時間には、コンテナとNode.jsの開始コストが含まれています。その後の呼び出しでは、約0.2秒と約0.5秒速くなりました。hotwrapのおかげで、Node.jsランタイムを起動しコードを実行するだけのコストで済みます。

The future of Hotwrap

Hotwrapはプロトタイプなので、本番環境では使用しないでください!とはいえ、元々はfunctionとして作成されていなかったプログラムをパッケージ化し、そのランタイム・パフォーマンスを向上する、Fnで提供するしくみの実現可能性およびその価値をHotwrapは示しています。FnではfunctionとしてDockerコンテナのデプロイをサポートしてきましたが、これらのfunctionではデフォルトのコンテナ・コントラクトを使う関係上、レイテンシが大きくなりました。Hotwrapはこの差異をある程度解決するものです。近い将来の公式なhotwrapユーティリティ(たぶん名前は変わると思います)の登場をお待ちください。
hotwrapを開発してくれたOwen Cliffeに感謝いたします。

[Cloud] Microservices From Dev To Deploy, Part 3: Local Deployment & The Angular UI

原文はこちら。
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy%2c-part-3%3a-local-deployment-the-angular-ui

この一連のエントリで、マイクロサービス・アプリケーションの構築方法を見てきました。Part 1でHelidonというOracleがリリースした新しいオープンソース・フレームワークと、Java(Microprofile)やGroovy(リアクティブ関数型スタイル)からの利用方法を知りました。
Microservices From Dev To Deploy, Part 1: Getting Started With Helidon
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon
https://orablogs-jp.blogspot.com/2018/10/microservices-from-dev-to-deploy-part-1.html
Part 2では、開発チームには強みと好みがあることを認識し、この架空のシナリオにおけるあるチームがNode.jsとExpressフレームワークを使ってマイクロサービスを開発したのに対し、もう一つのチームは、Oracleがリリースした、Fnというアプリケーションアーキテクチャにサーバーレスを追加するためのオープンソーステクノロジーを選択しました。
Microservices From Dev To Deploy, Part 2: Node/Express and Fn Serverless
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy,-part-2:-nodeexpress-and-fn-serverless
https://orablogs-jp.blogspot.com/2018/10/microservices-from-dev-to-deploy-part-2.html
以下は全体像をイメージしやすくするためのアーキテクチャ図です。

人為的でつまらないシナリオかもしれませんが、今日のソフトウェアを構築する多くのチームの真の現実であるスキルと好みの多様性を適切に表していると思います。このシナリオの最終ゴールは、このアプリケーションの全ての個別のサービスをすべてOracle Cloudにすることですが、まもなくその段階に到達します。しかしその前に、開発されたこれらのバックエンドサービスがすべて統一されたフロントエンドで纏めてるところを見ていきましょう。

その前に、自宅で試す場合は、まずローカルのKubernetesクラスタにアクセスできることを確認してください。 テスト目的で、Raspberry Piを使ってクラスタを構築しました(手順はこちら)が、minikubeを使えばローカルのテスト環境を速やかに立ち上げることができます。構成したクラスタで作業するには、コマンドラインツールが必要なので、kubectlのインストールを忘れないでください。
Install Minikube
https://kubernetes.io/docs/tasks/tools/install-minikube/
Install and Set Up kubectl
install https://kubernetes.io/docs/tasks/tools/install-kubectl/

環境が整ったら、Part 1でHelidon SEとGroovyを使って天気予報のバックエンドサービスを構築したChrisのチームを見てみましょう。Gradleの 'assemble'タスクでデプロイ用にJARファイルを生成しますが、Helidonには他にもいくつかの便利な機能が含まれています:K8Sクラスタへの展開をスピードアップするためのDockerfileとKubernetesのためのyamlテンプレートを生成します。(MichikoのチームがPart 1で行ったように)Mavenのarchetypeを使用すると、ファイルは自動的にJARと共に 'target'ディレクトリにコピーされますが、ChrisのチームはGradleでGroovyを使用しているため、テンプレートをコピーするためのビルドスクリプトを少々変更し、スクリプト内のPathを少々変更する必要がありました。ここで使用したbuild.gradleスクリプトには、以下のタスクが含まれています。
task copyDocker(type:Copy) {
    from "src/main/docker"
    into "build"
    doLast {
        def d = new File( 'build/Dockerfile' )
        def dfile = d.text.replaceAll('\\$\\{project.artifactId\\}', project.name)
        dfile = dfile.replaceAll("COPY ${project.name}", "COPY libs/${project.name}")
        d.write(dfile)
    }
}
task copyK8s(type:Copy) {
    from "src/main/k8s"
    into "build"
    doLast {
        def a = new File( 'build/app.yaml' )
        def afile = a.text.replaceAll('\\$\\{project.artifactId\\}', project.name)
        a.write(afile)
    }
}

copyLibs.dependsOn jar
copyDocker.dependsOn jar
copyK8s.dependsOn jar
assemble.dependsOn copyLibs
assemble.dependsOn copyDocker
assemble.dependsOn copyK8s
Chrisチームがローカルビルドを実行すると、完全に機能するDockerfileとapp.yamlファイルを受け取り、サービスを迅速にDockerコンテナにパッケージ化し、そのコンテナをKubernetesクラスタにデプロイできます。プロセスは次のようになります。
  1. コードを書く
  2. テスト
  3. JARを作成(gradle assembleを実行)
  4. Dockerコンテナを作成(docker build / docker tagを実行)
  5. Docker RegistryへPush(docker pushを実行)
  6. Kubernetesデプロイメントの作成(kubectl createの実行)
quick screencastにまとめてみました。

バックエンドサービスの残りに対してプロセスを繰り返した後に、Avaが率いるフロントエンドチームはバックエンドサービスをAngular 6で作成してきたフロントエンドに統合できるようになりました。デプロイ済みのバックエンドのベースURLをenvironment.tsファイルに設定するところから作業は始まります。Angularはこのファイルを使って環境毎に異なる値を持つグローバル・アプリケーション変数を柔軟に管理できます。たとえば、environment.prod.ts ファイルには、ng build --prodを実行すると置き換えられる、本番環境用の値セットを保持できます。環境を指定しない場合、デフォルトのenvironment.tsを使います。そのため、チームは開発環境向けにこのファイルを使い、以下の値を設定しました。
export const environment = {
  production: false,
  stockApiBaseUrl: 'http://192.168.0.160:31002',
  weatherApiBaseUrl: 'http://192.168.0.160:31000',
  quoteApiBaseUrl: 'http://192.168.0.160:31001',
  catApiBaseUrl: 'http://localhost:31004',
};
チームは各マイクロサービスに対応するサービスを作成しています。こちらはweather.service.tsです。
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class WeatherService {

  private baseUrl: string = environment.weatherApiBaseUrl;

  constructor(
    private http: HttpClient,
  ) { }

  getWeatherByCoords(coordinates) {
    return this.http
      .get(`${this.baseUrl}/weather/current/lat/${coordinates.lat}/lon/${coordinates.lon}`);
  }
}
viewコンポーネントからサービスを呼び出します。
getWeather() {
  this.weather = null;
  this.weatherLoading = true;

  this.locationService.getLocation().subscribe((result) => {
    const response: any = result;
    const loc: Array<string> = response.loc.split(',');
    const lat: string = loc[0];
    const long: string = loc[1];
    console.log(loc)
    this.weatherService.getWeatherByCoords({lat: lat, lon: long})
      .subscribe(
        (weather) => {
          this.weather = weather;
        },
        (error) => {},
        () => {
          this.weatherLoading = false;
        }
      );
  });
}
全てのサービスについて完了したら、先祖返りしたホームページという企業ビジョンはまもなく現実のものになろうとしています。


これらの3個のエントリで、アイデアからバックエンドサービス作成、そしてそれらをAngular 6で作ったモダンなJavaScriptベースのフロントエンドに統合するまでという、TechCorpのインターネット・ホームページアプリケーションの開発を開発するという旅路を辿ってきました。次回のエントリでは、この技術的に多様なアプリケーションのOracle Cloudへのデプロイをご紹介します。

[Cloud] Microservices From Dev To Deploy, Part 2: Node/Express and Fn Serverless

原文はこちら。
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy%2c-part-2%3a-nodeexpress-and-fn-serverless

前回のエントリで、Lydiaという創業者が運営するTechCorpという架空の会社を紹介しました。彼女はインターネット・ホームページのすばらしき日々を取り戻そうとしています。
Microservices From Dev To Deploy, Part 1: Getting Started With Helidon
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon
https://orablogs-jp.blogspot.com/2018/10/microservices-from-dev-to-deploy-part-1.html
Lydiaの会社のグローバルチームはすばらしい開発者で構成されており、彼らは彼女のビジョンをマイクロサービス・アーキテクチャで実装しています。すでに我々はLondonのChrisのチームと東京のMichikoのチームの情報を知っています。これらのチームは天気および名言のサービスをHelidonというOracleが作ったマイクロサービス・フレームワークで構築しました。
Helidon
https://helidon.io/
ChrisのチームはHelidon SEをGroovyから利用し、MichikoのチームはHelidon MPとJavaを選択しています。このエントリでは、MurielleとそのBangaloreのチームがNode.jsとExpressを使って株価サービスを作成し、DominicとそのMelbourneのチームがJavaとFn Project(サーバーレス・テクノロジー)を使ってランダムに猫の画像を出すサービスの構築といううらやましい作業をしているところを見ていきます。
Fn Project
https://fnproject.io/
Helidonを使えば関数型スタイルとMicroprofileスタイルのサービスの両方を簡単に実装できます。 しかし、個人的に5年前に考えていたことではありますが、NodeJSの人気は無視できません。Stack Overflowの最近の調査によると、プログラミング、スクリプト、マークアップ言語の中で最も人気のある技術としてJavaScriptを選択した回答者は69%を超えており、かつ、回答者の49%以上が「フレームワーク」カテゴリの最上位にNodeを位置づけています。
Stack OverFlow Developer Surveys - Most Popular Technologies
https://insights.stackoverflow.com/survey/2018#technology
これは、人々がフロントエンドでJavaScriptを使用するのは当然として、ますますバックエンドでJavaScriptを活用しようとしているということです。そのため、Murielleのチームは、ExpressとNodeを使用して株価サービスを構築することにしました。

このサービスを作成するためのExpressについて深掘りはしませんが、株価の取得方法を簡単に見てみましょう。
var express = require('express');
var router = express.Router();
var config = require('config');
var fetch = require("node-fetch");

/* GET stock quote */
/* jshint ignore:start */
router.get('/quote/:symbol', async (req, res, next) => {
  const symbol = req.param('symbol');
  const url = `${config.get("api.baseUrl")}/?function=GLOBAL_QUOTE&symbol=${symbol}&apikey=${config.get("api.apiKey")}`;
  
  try {
    const response = await fetch(url);
    const json = await response.json();
    res.send(json);
  } catch (error) {
    res.send(JSON.stringify(error));
  }

});
/* jshint ignore:end */
module.exports = router;
(非同期呼び出しで)fetchを使っています。このメソッドは株価APIを呼び出し、URLパラメータを使って受け取ったティッカーシンボルを渡して、株価をJSON文字列としてAPI呼び出し元に返します。ローカルでサービスを実行したときの様子は以下の通りです。

Murielleのチームは、将来的にサービスを拡張して履歴データ、暗号通貨のルックアップなど、ビジネスが必要とするものすべてを提供できますが、現時点では、受け取ったティッカーシンボルに基づいて現在の株価を返します。チームは今後のデプロイのためにDockerfileとKubernetesの設定ファイルを作成しています。

MelbourneのDominicのチームは、サーバーレス・テクノロジーをこれまでよく使ってきています。彼らは優先機能、つまりランダムな猫の画像を提供する機能を任されており、サーバーレス(テクノロジー)を使ってこの機能を提供すべきで、Fnを使ってサービスの構築に着手しようと考えています。

マイクロサービスアーキテクチャではサーバレスを考慮する必要はありませんが、サーバーレスを使えば、柔軟性に富み、スケーラブル、集中性、迅速なデプロイが可能という、マイクロサービス・アプローチの目標を達成できるでしょう。DominicのチームはサーバーレスとFnに関して調査を完了し、作業準備が整ったので、開発者はローカルFnサーバーをインストールし、Javaのクイックスタートに従ってfunctionのテンプレートを作成しました。
Serverless with Fn Project
https://developer.oracle.com/opensource/serverless-with-fn-project
Install Fn
https://fnproject.io/tutorials/install/
Introduction
https://fnproject.io/tutorials/JavaFDKIntroduction/
プロジェクトの準備完了後、Dominicのチームはfunc.yamlファイルを修正して、プロジェクトの設定、特にapiBaseUrlとapiKeyを設定しました。
schema_version: 20180708
name: cat-svc
version: 0.0.47
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk9-1.0.70
run_image: fnproject/fn-java-fdk:jdk9-1.0.70
cmd: codes.recursive.cat.CatFunction::handleRequest
format: http
config:
  apiBaseUrl: https://api.thecatapi.com/v1
  apiKey: [redacted]
triggers:
- name: cat
  type: http
  source: /random
CatFunctionクラスは基本的なもので難しくはありません。@FnConfigurationで注釈を付けられたsetUp()メソッドは、YAMLファイルの設定情報を含むfunctionコンテキストにアクセスし、関数の変数を初期化します。handleRequest()メソッドはUnirestというクライアントライブラリを使用してHTTP呼び出しを行い、すばらしい猫の画像へのリンクを含むJSONを返します。
public class CatFunction {

    private String apiBaseUrl;
    private String apiKey;

    @FnConfiguration
    public void setUp(RuntimeContext ctx) {
        apiBaseUrl = ctx.getConfigurationByKey("apiBaseUrl").orElse("");
        apiKey = ctx.getConfigurationByKey("apiKey").orElse("");
    }

    public OutputEvent handleRequest(String input) throws UnirestException {
        String url = apiBaseUrl + "/images/search?format=json";
        HttpResponse<JsonNode> response = Unirest
                .get(url)
                .header("Content-Type", "application/json")
                .header("x-api-key", apiKey)
                .asJson();
        OutputEvent out = OutputEvent.fromBytes(
                response.getBody().toString().getBytes(),
                OutputEvent.Status.Success,
                "application/json"
        );
        return out;
    }
}
functionのテストのため、ローカルのFnサーバーにデプロイして…
fn deploy --app cat-svc –local
動作確認すると…
curl -i \
-H "Content-Type: application/json" \
http://localhost:8080/t/cat-svc/random
以下のような結果が返ってきます。
HTTP/1.1 200 OK
Content-Length: 112
Content-Type: application/json
Fn_call_id: 01CRGBAH56NG8G00RZJ0000001
Xxx-Fxlb-Wait: 502.0941ms
Date: Fri, 28 Sep 2018 15:04:05 GMT
[{"id":"ci","categories":[],"url":"https://24.media.tumblr.com/tumblr_lz8xmo6xYV1r0mbi6o1_500.jpg","breeds":[]}]
うまく動作しました。Dominicのチームは昼食前に猫のサービスを作成し、残りの時間はランダムに表示される猫の画像を見て過ごしました。

さまざまなテクノロジーを使い、4チーム全てが任されたサービスの実装が完了しました。フロントエンドからサードパーティAPIを直接呼び出すのではなく、バックエンドにこのような簡単なサービスを実装する必要性​​を自問していらっしゃるかもしれません。理由はいくつかありますが、一部を見ていきましょう。

サーバーベースのバックエンド経由でこの機能を実装する理由の1つとして、サードパーティのAPIが信頼性が低かったり、レート制限があったりする可能性があります。独自のバックエンドを介してAPIをプロキシすることで、チームはキャッシュや独自に設計したレート制限を活用できるます。サードパーティAPIへのリクエストや、制限付きで管理できたり管理不可のサービスの潜在的なダウンタイムやレート制限の回避をする必要はなくなります。

第二に、チームはデータをクライアントに送信する前に制御できる、という点です。条件やビジネスニーズにより、他のサードパーティまたはユーザーデータでデータを補うことがAPI内で可能であれば、クライアント到達前にデータの追加、変更によってクライアントのCPU、メモリ、帯域幅の要件を削減できます。

最後に、ブラウザによるCORSの制約は、サーバーからAPIを呼び出すことで回避できます(CORS制約の結果ブラウザからのHTTP呼び出しをブロックを経験している場合には、このメリットは理解いただけると思います)。

TechCorp はこれでプロジェクトの最初のマイクロサービス開発のスプリントを完了しました。次回のエントリでは、4個のサービスをローカルのKubernetesクラスタにデプロイする方法と、Angularで作成するフロントエンドを深く見ていきます。

[Java] Building JDK 11 Together

原文はこちら。
https://blogs.oracle.com/java-platform-group/building-jdk-11-together

先日Java 11がリリースされました。
Introducing Java SE 11
https://blogs.oracle.com/java-platform-group/introducing-java-se-11
https://orablogs-jp.blogspot.com/2018/09/introducing-java-se-11.html
新しい6ヵ月のリリースサイクルで2回目の機能リリース(feature release)の開発を振り返ることにします。多くの個人や団体からのOpenJDKコミュニティへの多くの貢献を祝いましょう。みんなでJDK 11を一緒に作りました!

JDK 11 Fix Ratio

JDKの全体的な変更の割合は、基本的に長年にわたって一定でしたが、新しいサイクルになってから、変更が利用可能になるまでのスピードが劇的に増加しました。数年ごとに何万もの修正と約100個のJEPSを一度に大量にリリースするのではなく、より小規模なリリースで、より管理しやすく予測可能なスケジュールで変更を利用可能にします。これらの変更は、大規模な機能から小さな機能強化、定期的なメンテナンス、バグ修正、およびドキュメントの改善までさまざまです。変更の各々はJDK Bug Systemの1個のIssueに対する1個のCommitで表現されます。
JDK Bug System
http://bugs.openjdk.java.net/
JDK 11で修正済みとされている2468件のJIRAのIssueのうち、1963件はOracleでの従業員によって完了し、505件は個人の開発者や他の組織で働く開発者からの貢献によるものでした。Issueの調査と担当者から組織データを照合した結果、下図のJDK 11の修正開発を支援する組織のグラフができあがりました。
Issues fixed in JDK 11 per organization
Oracleが採用した開発者が、JDK 11開発中にJIRAのIssueの80%を解決し、他の組織の開発者が20%を修正しました。Oracleを除く、Issueを解決した開発者の所属組織トップ5はSAP(7%)、Red Hat(5%)、Google(3%)、BellSoft(1%)、IBM(1%)で、合計17%のIssueを修正しました。JDK 11の修正の2%は個人開発者による貢献でした。

大事なことを言い忘れていましたが、修正の残りの1%は幅広い組織の開発者による貢献でした。具体的には、Alibaba、Amazon、ARM、Azul、Intel、JetBrains、Linaro、およびQualcomm Datacenter Technologiesなどです。

But wait, there’s more

個々のコミットに加えてJDKリリースには、JDKプロジェクトとJDK 11向けの機能や修正が行われたさまざまなOpenJDKプロジェクトの両方で、JEP、コードレビュー、バグレポート、メーリングリストでの議論など、さらに多くの作業があります。
jdk-dev -- Technical discussion related to the JDK Project
http://mail.openjdk.java.net/mailman/listinfo/jdk-dev
これには、OracleのBrian Goetzが率いるProject ValhallaとProject Amber、Red HatのAndrew Haleyが率いるAArch64 Port、OracleのPer Lidénが率いるZGC Projectが含まれます。
Valhalla
https://wiki.openjdk.java.net/display/valhalla
Project Amber
http://openjdk.java.net/projects/amber
AArch64 Port Project
http://openjdk.java.net/projects/aarch64-port/
ZGC
https://wiki.openjdk.java.net/display/zgc
JDK 11のリリースが終わって、JDK Updates Projectのリポジトリで最初のOracleが提供するJDK 11アップデートの作業も始まりました。
[11u Communication] jdk11u forest
http://mail.openjdk.java.net/pipermail/jdk-updates-dev/2018-September/000145.html

Thank you for JDK 11, everyone!

最後に、JDK 11にコードを提供くださったすべての開発者とそのスポンサー組織に感謝申し上げます。提案された変更をレビューした多くの経験豊富な開発者、早期アクセスビルドを試して問題を報告してくださったEarly Adopter、OpenJDKメーリングリストにフィードバックしてくださったプロフェッショナルの皆様には非常に感謝しております。

[Cloud] Microservices From Dev To Deploy, Part 1: Getting Started With Helidon

原文はこちら。
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon

マイクロサービスは間違いなく普及しています。アプリケーションを構築するためのマイクロサービスのアプローチ(または「マイクロサービスのアプローチを使うべき理由」)を使う利点を説明するエントリが多数あります。
Getting Started with Microservices, Part 1: Advantages and Considerations
http://blogs.oracle.com/developers/getting-started-with-microservices-part-one
Getting Started with Microservices, Part 2: Containers and Microservices
http://blogs.oracle.com/developers/getting-started-with-microservices-part-two
Getting Started with Microservices, Part 3: Basic Patterns and Best Practices
http://blogs.oracle.com/developers/getting-started-with-microservices-part-three
Getting Started with Microservices, Part 4: Fundamentals of DevOps with Containerized Microservices
https://blogs.oracle.com/developers/getting-started-with-microservices-part-four
その理由はたくさんありますが、チームが言語/フレームワークを自由に選択しつつ、独立したデプロイメント、スケーラビリティ、およびビルド時間とテスト時間の異なるサービスを実装できるという柔軟性は、とりわけマイクロサービスアプローチが今日の多くの開発チームにとって望ましいものである多くの要因の1つです。調査の結果、約86%の回答者がマイクロサービスのアプローチが今後5年間でデフォルトのアーキテクチャになると信じていることから、これ以上の議論は不要でしょう。
New study shows rapid growth in microservices adoption among enterprises
https://siliconangle.com/2018/05/02/new-study-shows-rapid-growth-microservices-adoption-among-enterprises/
前述の通り、「マイクロサービスでなければならない理由(Why microservices)」への回答はこれまでにあったので、この短いエントリでは、あなたの組織でマイクロサービスを実装する方法についての質問に答えてまいります。具体的には、お客様の開発チームがメンテナンス可能で拡張性の高い、簡単にテスト、開発、デプロイできるマイクロサービスアプリケーションのソリューションをOracleのテクノロジーがご支援できる点を紹介します。

話を面白くするため、このエントリのための架空のシナリオを思いつきました。TechCorpという名前のスタートアップ企業が、素晴らしいプロジェクトのために開業資金として1億5000万USDを確保したとしましょう。TechCorpの創業者であるLydiaは非常にノスタルジックで、56kモデムがピーガー言って"interwebs"へとつながった古き良き日を懐かしく思っており、パーソナライズされたホームページが大きく復活するとBigCity Venture Capitalを納得させてきました。天気、金融情報、ニュース、それだけでなく、あなたの一日を明るくするインスパイアさせる言葉や面白い猫の写真…があったのを覚えていますよね?そこでLydiaは資金を確保し、世界中にイケてる開発者のチームを持つ多国籍企業をつくることになりました。LydiaとCTOのRajはマイクロサービスについて熟知しており、チームを分割してバックエンドの個々のパートに携わってもらい、マイクロサービスの強みを活かして、柔軟で信頼できるアーキテクチャを確実にする計画を立てています。
Team #1:
Location: London
Team Lead: Chris
Focus: Weather Service
Language: Groovy
Framework: Oracle Helidon SE with Gradle

Team #2:
Location: Tokyo
Team Lead: Michiko
Focus: Quote Service
Language: Java
Framework: Oracle Helidon MP with Maven

Team #3:
Location: Bangalore
Team Lead: Murielle
Focus: Stock Service
Language: JavaScript/Node
Framework: Express

Team #4:
Location: Melbourne
Team Lead: Dominic
Focus: Cat Picture Service
Language: Java
Framework Oracle Fn (Serverless)

Team #5
Location: Atlanta
Team Lead: Ava
Focus: Frontend
Language: JavaScript/TypeScript
Framework: Angular 6
ご覧のように、Lydiaは幅広いスキルと経験を備えた多種多様なチームを集めています。選択されたものの中には、Oracle以外のテクノロジーもあることにお気づきかと思います。Oracleテクノロジにフォーカスしたブログエントリでは奇妙な点があるかもしれませんが、これは今日の多くのソフトウェア企業の様子を表しています。チームが単一の企業のスタックだけに集中することはほとんどありません。そうしてもらえるといいのですが、現実的には、チームにはその強みと好みがあります。この一連のエントリでは、Oracleの新しいオープンソース・フレームワークであるHelidonとServerlessのためのFn projectを活用して、マイクロサービスとServerless functionをビルドするだけでなく、チームがOracle Cloudに全てのスタックをデプロイできる点をご紹介します。
Helidon
https://helidon.io
Fn Project
https://fnproject.io
Helidonについては、紹介記事よりも少し詳しく紹介しますので、最初に以下の紹介記事とチュートリアルを読んでから、この記事の残りの部分を読んでください。
Helidon Takes Flight
https://medium.com/oracledevs/helidon-takes-flight-fb7e9e390e9c
https://orablogs-jp.blogspot.com/2018/09/helidon-takes-flight.html
Tutorial
http://helidon.io/docs/latest/#/about/01_introduction
Team #1は、ユーザーのいる場所の天気を取得するためのバックエンドの構築を任されています。Team #1はGroovyに強みを持つチームですが、Oracleの新しいマイクロサービスフレームワークであるHelidonについて良い話を聞いたので、この新しいHelidonを学びながら、ビルドツールのGroovyとGradleと一緒に使えるのかを確認することにしました。チームリーダーのChrisはHelidonのチュートリアルを読み、クイックスタートのサンプルを使って新しいアプリケーションを作成しました。
Getting-started  —  Quickstart Examples
https://helidon.io/docs/latest/#/getting-started/02_base-example
そのため、作成されたJavaアプリケーションをGroovyアプリケーションに変換することが彼の最初の作業です。この場合、Chrisはまず最初にGradleのビルドファイルを作成し、GroovyとHelidonのそれぞれの依存関係が全て含まれていることを確認する必要があります。Chrisはプロジェクトビルド時に依存関係のすべてがプロジェクトのビルド時に必要な場所に配置されるよう、'copyLibs'タスクも追加しておく必要があります。以下はbuild.gradleファイルの例です。
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'groovy'
apply plugin: 'application'

mainClassName = 'codes.recursive.weather.Main'

group = 'codes.recursive.weather'
version = '1.0-SNAPSHOT'

description = """A simple weather microservice"""

sourceSets.main.resources.srcDirs = [ "src/main/groovy", "src/main/resources" ]

sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

ext {
    helidonversion = '0.10.0'
}

repositories {
    maven { url "http://repo.maven.apache.org/maven2" }
    mavenLocal()
    mavenCentral()
}

configurations {
    localGroovyConf
}

dependencies {
    localGroovyConf localGroovy()
    compile 'org.codehaus.groovy:groovy-all:3.0.0-alpha-3'
    compile "io.helidon:helidon-bom:${project.helidonversion}"
    compile "io.helidon.webserver:helidon-webserver-bundle:${project.helidonversion}"
    compile "io.helidon.config:helidon-config-yaml:${project.helidonversion}"
    compile "io.helidon.microprofile.metrics:helidon-metrics-se:${project.helidonversion}"
    compile "io.helidon.webserver:helidon-webserver-prometheus:${project.helidonversion}"
    compile group: 'com.mashape.unirest', name: 'unirest-java', version: '1.4.9'
    testCompile 'org.junit.jupiter:junit-jupiter-api:5.1.0'
}

// define a custom task to copy all dependencies in the runtime classpath
// into build/libs/libs
// uses built-in Copy
task copyLibs(type: Copy) {
  from configurations.runtime
  into 'build/libs/libs'
}

// add it as a dependency of built-in task 'assemble'
copyLibs.dependsOn jar
copyDocker.dependsOn jar
copyK8s.dependsOn jar
assemble.dependsOn copyLibs
assemble.dependsOn copyDocker
assemble.dependsOn copyK8s

// default jar configuration
// set the main classpath
jar {
  archiveName = "${project.name}.jar"
    manifest {
        attributes ('Main-Class': "${mainClassName}",
                'Class-Path': configurations.runtime.files.collect { "libs/$it.name" }.join(' ')
               )
    }
}
ビルドスクリプトを設定し、Chrisのチームはアプリケーションをビルドします。Helidon SEは、シンプルなサービスを簡単に構築できます。まず始めに、以下のクラスだけが必要です。Main.groovy(GradleスクリプトがMain.groovyへのパスを使ってmainClassNameを識別していることに注目してください)は、サーバーを作成し、ルーティングを設定、エラー処理を設定し、オプションでメトリックを設定します。以下はMain.groovyです。
final class Main {

    private Main() { }

    private static Routing createRouting() {
        MetricsSupport metricsSupport = MetricsSupport.create()

        MetricRegistry registry = RegistryFactory
                .getRegistryFactory()
                .get()
                .getRegistry(MetricRegistry.Type.APPLICATION)
        return Routing.builder()
                .register("/weather", new WeatherService())
                .register(metricsSupport)
                .error( NotFoundException.class, {req, res, ex ->
                    res.headers().contentType(MediaType.APPLICATION_JSON)
                    res.status(404).send(new JsonGenerator.Options().build().toJson(ex))
                })
                .error( Exception.class, {req, res, ex ->
                    ex.printStackTrace()
                    res.headers().contentType(MediaType.APPLICATION_JSON)
                    res.status(500).send(new JsonGenerator.Options().build().toJson(ex))
                })
                .build()
    }

    static void main(final String[] args) throws IOException {
        startServer()
    }

    protected static WebServer startServer() throws IOException {

        // load logging configuration
        LogManager.getLogManager().readConfiguration(
                Main.class.getResourceAsStream("/logging.properties"))

        // By default this will pick up application.yaml from the classpath
        Config config = Config.create()

        // Get webserver config from the "server" section of application.yaml
        ServerConfiguration serverConfig =
                ServerConfiguration.fromConfig(config.get("server"))

        WebServer server = WebServer.create(serverConfig, createRouting())

        // Start the server and print some info.
        server.start().thenAccept( { NettyWebServer ws ->
            println "Web server is running at http://${config.get("server").get("host").asString()}:${config.get("server").get("port").asString()}"
        })

        // Server threads are not demon. NO need to block. Just react.
        server.whenShutdown().thenRun({ it ->
            Unirest.shutdown()
            println "Web server has been shut down.  Goodbye!"
        })

        return server
    }
}
Heldion SEはsrc/main/resourcesにapplication.yamlという名前のYAMLファイルを配置し、このファイルを構成目的で使います。サーバー関連の構成だけでなく、任意のアプリケーションの変数をこのファイルに格納できます。ChrisのチームはAPI関連の変数をこのファイルに記載しています。
app:
  apiBaseUrl: "https://api.openweathermap.org/data/2.5"
  apiKey: "[redacted]"

server:
  port: 8080
  host: 0.0.0.0
Mainクラスに戻ると、13行目で/weatherというエンドポイントを登録しており、WeatherServiceを示すことがわかります。このクラスは天気のデータを取得することになったときに働きます。Helidon SEサービスはServiceインターフェースを実装します。このクラスにはupdate()メソッドがあり、このメソッドを使って指定されたサービスへのサブルートを確立し、これらのサービスクラスのプライベート・メソッドでサブルートを指し示します。Chrisのチームは以下のようなupdate()メソッドを作成しました。
void update(Routing.Rules rules) {
    rules
        .any(this::countAccess as Handler)
        .get("/current/city/{city}", this::getByLocation as Handler)
        .get("/current/id/{id}", this::getById as Handler)
        .get("/current/lat/{lat}/lon/{lon}", this::getByLatLon as Handler)
        .get("/current/zip/{zip}", this::getByZip as Handler)
}
Chrisのチームは、消費者に現在の天気を(都市、ID、緯度/経度または郵便番号)という4つの別々の方法で提供する4個の異なるルートを"/weather"配下に作成します。Groovyを使っているので、メソッド参照をio.helidon.webserver.Handlerとしてキャストする必要があります(キャストしないと例外が発生します)。メソッドの一つであるgetByZip()を見てみましょう。
private void getByZip(ServerRequest request, ServerResponse response) {
    def zip = request.path().param("zip")
    def weather = getWeather([ (ZIP): zip ])
    response.headers().contentType(MediaType.APPLICATION_JSON)
    response.send(weather.getBody().getObject().toString())
}
getByZip()メソッドはパラメータZip(郵便番号)をリクエストから拾いだし、getWeather()を呼び出します。この際にUnirestと呼ばれるクライアントライブラリを使って選択したweather APIへのHTTP呼び出しを行い、現在の天気をgetByZip()に返し、JSONとしてブラウザにレスポンスを送信します。
Unirest for Java
http://unirest.io/java.html
private HttpResponse<JsonNode> getWeather(Map params) {
    return Unirest
        .get("${baseUrl}/weather?${params.collect { it }.join('&')}&appid=${apiKey}")
        .asJson()
}
ご覧の通り、ルータが呼び出した際に各サービスメソッドは、渡ってきた2個の引数であるリクエストとレスポンス(以前マイクロサービス・フレームワークを使ったことがあれば推測できるかと思いますが)を取得します。これらの引数を使って開発者はURLパラメータ、フォームデータ、HTTPヘッダーをリクエストから取得し、ステータス、メッセージ本体、HTTPヘッダーを必要に応じてレスポンスに設定します。このチームがweatherサービスの全体を構築すると、Gradleのrunタスクを実行して全てがブラウザで問題なく動作するか確認する準備ができあがります。

ロンドンは曇ですか…。

Helidon SEには他にも色々ありますが、おわかりの通り、基本的なマイクロサービスを稼働させるためには多くのコードを必要としません。後のエントリでサービスのデプロイ方法を見ていきますが、Helidonは手順を簡単にするために、DockerfileとKubernetesの設定ファイルの作成をサポートしています。

ではMichikoのチームを見てみましょう。このチームにはランダムに名言(Quote)を返すバックエンドの構築を任されています。このような機能がなければパーソナライズされたホームページではないためです。この東京のチームはJavaでコードを作成し、Mavenを使用してコンパイルと依存関係を管理していて、MicroProfileのAPIのことをよく知っています。
MicroProfile
https://microprofile.io/
MichikoとそのチームもHelidonを使用することに決めましたが、MicroProfileに詳しいため、よりリアクティブで関数型スタイルを使うSEではなく、長年使ってきたJAX-RSやCDIのようなよく知っているAPIを提供していることから、Helidon MPを使うことに決めました。Chrisのチームのように、MPのquickstart archetypeを使ってスケルトンアプリケーションをさくっと作成し、Main.javaクラスの設定を開始します。
Getting-started  —  Quickstart Examples
https://helidon.io/docs/latest/#/getting-started/02_base-example
M ainクラスの主なメソッドはstartServer()を呼び出します。このメソッドはSEのメソッドとは若干異なりますが、同じタスクを実行します。具体的には構成ファイル(/src/main/resources/META-INF にあるmicroprofile-config.propertiesというファイル)を使ってアプリケーションサーバを起動します。
protected static Server startServer() throws IOException {
    // load logging configuration
    LogManager.getLogManager().readConfiguration(
            Main.class.getResourceAsStream("/logging.properties"));
    // Server will automatically pick up configuration from
    // microprofile-config.properties
    Server server = Server.create();
    server.start();
    return server;
}
続いて、CDI実装がクラスを拾い上げることができるよう、 /src/main/resources/META-INF にbeans.xmlを作成します。
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans>
</beans>
JAX-RSアプリケーションを作成し、必要に応じてリソースクラスを追加します。
@ApplicationScoped
@ApplicationPath("/")
public class QuoteApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> set = new HashSet<>();
        set.add(QuoteResource.class);
        return Collections.unmodifiableSet(set);
    }
}
QuoteResourceクラスを作成します。
@Path("/quote")
@RequestScoped
public class QuoteResource {

    private static String apiBaseUrl = null;

    @Inject
    public QuoteResource(@ConfigProperty(name = "app.api.baseUrl") final String apiBaseUrl) {
        if (this.apiBaseUrl == null) {
            this.apiBaseUrl = apiBaseUrl;
        }
    }

    @SuppressWarnings("checkstyle:designforextension")
    @Path("/random")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getRandomQuote() throws UnirestException {
        String url = apiBaseUrl + "/posts?filter[orderby]=rand&filter[posts_per_page]=1";
        HttpResponse<JsonNode> quote = Unirest.get(url).asJson();
        return quote.getBody().toString();
    }
}
構成プロパティを取得するためにコンストラクタインジェクションを使用し、パスやHTTPメソッド、レスポンスのContent Typeのためにシンプルなアノテーションを使っている点に注目してください。getRandomQuote()メソッドはUnirestを使ってquote APIを呼び出し、結果をJSON文字列として戻します。mvnパッケージタスクを実行し、結果として生じるJARを実行すると、アプリケーションが起動し、以下のような結果が得られます。

ユーザベースの拡大と興奮した投資家からの追加資金の調達に伴い、時間の経過とともにサービスが成長する柔軟な基盤上に、Michikoのチームは名言のマイクロサービスの初期実装を成功裏に構築しました。SEバージョンと同様、Helidon MPはデプロイの一助となるDockerfileとKubernetesのapp.yamlファイルを生成します。後ほどデプロイを見ていきましょう。

このエントリでは、莫大な資金を調達した、インターネット・ホームページ・アプリケーションのためのマイクロサービスに踏み入ったの架空のスタートアップ企業について説明しました。Helidonというマイクロサービス・フレームワークは、リアクティブで関数型のスタイルを提供するバージョンだけでなく、JAX-RSやCDIに慣れ親しんだJava EEの開発者により適したMicroProfileバージョンも提供していることを知りました。Lydiaのチームは、バックエンドのアーキテクチャの構築を急速に進めており、TechCorpのビジョンを実現するのにもう少しの所まで近づいています。次回のエントリでは、MurielleとDominicのチームがサービスをどのように構築するのかを見ていきます。将来のエントリでは、すべてのチームが最終的にどのようにサービスをテストし、運用に入っていくのかを見ていくことにしています。

[Cloud] CI/CD on Steroids: Announcing Container Engine for Kubernetes as a Jenkins X Provider

原文はこちら。
https://blogs.oracle.com/cloud-infrastructure/cicd-on-steroids%3a-announcing-container-engine-for-kubernetes-as-a-jenkins-x-provider


Kubernetesが分散コンテナアプリケーションの管理ツールのデファクトになりました。今日クラウドアプリケーションを作って本当にマルチクラウドに対応させ、かつ可搬性を持たせたいのであれば、Kubernetesを選択するかしないかはあなた次第です。

Kubernetesはすばらしいものですが、継続的デリバリ(CD)スタイルでKubernetes上にアプリケーションを作成したい場合や開発者に生産性を高めて欲しい場合には、課題がいくつかあります。これまでのJenkins(Jenkins 2.0)を使うと、継続的デリバリシステムをKuberenetesで実装できますが、以下のような手順があり面倒です。
  • Kubernetes用のJenkinsプラグインの設定
  • KubernetesクラスタおよびKubernetes環境の設定
  • パイプラインの設定
  • Kubernetesへのコンテナのデプロイ
  • YAMLやHelm Chartの生成
  • 継続的デリバリの採用と推進

Jenkins X

Jenkins Xは、Jenkinsの主要なCI/CDの専門知識と業界の顧客層を活用し、Kubernetes環境に自然に適合するCI/CDソリューションを提供します。Jenkins Xでは、Kubernetesオペレーションの総合的な理解や実行は不要で、Kubernetes環境での製品(=アプリケーション)の出荷速度を大幅に向上させることができます。Dockerfileを扱ったり、Helm Chartを調整したり、jenkinsfileを書いたりする必要はありません。ただ、アプリケーションを作成すれば、それでOKです。すべてのCI/CDが自動実行されます。

Jenkins Xでは以下の操作が簡単になります。
  • Kubernetesの展開に必要なツールのインストールとアップグレードを自動化します。これらのツールはすべてKubernetes向けに構成および最適化されています。ツールには以下のものを含みます。
    • Helm(Kubernetesのパッケージマネージャ)
    • Draft(Kubernetes上でビルド、実行するためのアプルケーションを起動する際に使われるビルドパック)
    • Skaffold(RAD開発を可能にし、イメージのビルドやプッシュを簡素化)
    • Kaniko
    • Jenkins
    • Ksync
    • Monocular
    • Nexus
  • KuberenetesでアプリケーションのCI/CDを自動化
    • Dockerイメージ
    • Helm charts
    • パイプライン
  • GitOpsを利用し、(テストからステージング、本番)


2018年7月現在、Oracle Cloud InfrastructureはJenkins Xのオフィシャルなクラウドで、Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)でのJenkins Xの実行をネイティブサポートしています。このプロジェクトに参画、貢献してくれたChenghao Shi、Hui Liuおよび彼らのチームの皆様に感謝します。

Run Jenkins X in OKE

Jenkins XをOKEで実行するには2方法あります。このエントリでは、jxというJenkins Xコマンドラインツールの利用方法とこれらの操作の実行方法を紹介します。
  • Jenkins Xがインストールされた新規のOKEクラスタを作成(jx create コマンドを利用)
  • 既存のOKEクラスタにJenkins Xをインストール(jx install コマンドを利用)

Create a New OKE Cluster and Install Jenkins X

jxツールはOracle Cloud Infrastructure CLIを使ってOKEと通信します。CLIがクラスタ作成時点で未インストールの場合、jxは依存関係のあるCLIがないと判断し、実行時にCLIをインストールします。

以下は新規OKEクラスタを作成し、Jenkins Xをクラスタにインストールする手順です。

注意: 実行前に、OKEクラスタデプロイのための必要なサブネットやセキュリティ・リスト・ルール、IAMポリシーが構成済みであることを確認してください。現リリースのjxはこれらを作成しません。これらのリソースの作成方法の詳細は、以下のドキュメントをご覧ください。
Preparing for Container Engine for Kubernetes
https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengprerequisites.htm?tocpath=Services%7CContainer%20Engine%7CPreparing%20for%20Container%20Engine%20for%20Kubernetes%7C_____0
これらの必要なリソースを迅速にプロビジョニングするためにTerraformのコードを使うこともできます(訳注:原文にはリンクがありますが、空っぽなので訳文ではリンクを掲載していません)。これらのリソースが準備できたら、jxを使ってingress controller、PVCなどを作成してから、Kubernetesに関連するユーティリティやJenkins Xのインストールを始めます。
  1. 開発タスクを実行するようGitを構成します。
    sudo yum install git -y
  2. kubectlをインストールします。
    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
    chmod +x ./kubectl
    sudo mv ./kubectl /usr/local/bin/kubectl
  3. jxがどのOCIリソースを使うのかわかるよう、oci configファイルを構成します。CLIはこの時点ではインストールされません(実行中にインストールされます)。
    mkdir ~/.oci
    vi ~/.oci/config
    vi ~/.oci/oci_api_key.pem
    chmod 600 ~/.oci/config ~/.oci/oci_api_key.pem
  4. OKEクラスタにインストールされるHelmサーバのtillerと会話できるよう、Helmクライアントをインストールします。
    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz
    tar -xvf helm-v2.9.1-linux-amd64.tar.gz
    sudo mv linux-amd64/helm /usr/local/bin/
  5. jx コマンドラインツールをインストールします。
    curl -L https://github.com/jenkins-x/jx/releases/download/v1.3.52/jx-linux-amd64.tar.gz | tar xzv
    sudo mv jx /usr/local/bin
  6. jxを使い、Jenkins XがインストールされたOKEクラスタを作成します。
    jx create cluster oke [flags]
    多数のフラグを指定できます。これらのフラグの一部はOracle Cloud Infrastructureに固有のもので、残りはjxの汎用的なフラグです。例えば、次のフラグを使用してOKEクラスタを作成することも、 jx create cluster okeコマンドだけを実行して、実行時に必要なOCIDを入力することもできます。
    jx create cluster oke --name shoulderroad --compartment-id ocid1.tenancy.oc1..l3d6xxx4gziexn5sxnldyhja --vcn-id ocid1.vcn.oc1.phx.ofu4bbmfhj5ijidyde3gpdocybghidrmbq --kubernetes-version v1.10.3 --wait-for-state SUCCEEDED --serviceLbSubnetIds file:///tmp/oke_cluster_config.json --tiller-enabled false
    このコマンドは、OKEに新規Kubernetesクラスタを作成し、必要なローカルの依存関係をインストールし、Jenkins Xプラットフォームをプロビジョニングします。$HOME/binを$PATHに追加してください。 そうしないと、jxはCLIコマンドを呼び出し時に問題が発生します。すでにCLIをインストールしている場合は、CLIが$PATHにあることを確認してください。

    コマンドが完了すると、Jenkins、Nexus、Dockerレジストリ、ChartMuseum、Monocularなどを含む開発環境と、その他の環境(ステージングや本番)ができあがります。通常は、これらのgitリポジトリのHelm chartを使用して、インストール対象のchartやバージョン、任意の環境固有の構成や追加リソースを定義します。
  7. 以下のコマンドを実行して環境を確認します。
    kubectl get svc --all-namespaces
    以下のような出力結果を確認できるはずです。

Install Jenkins X on an Existing OKE Cluster

既存のOKEクラスタがある場合、jxコマンドを使ってJenkins Xをインストールできます。
  1. まず、以下のコマンドを実行して環境の準備をします。
    chmod +x ~/get-kubeconfig.sh
    
    export ENDPOINT=containerengine.us-phoenix-1.oraclecloud.com
    
    ~/get-kubeconfig.sh ocid1.cluster.oc1.phx.rdsztcmnstcnjsgy4taytcmctdqyrzheyw > ~/kubeconfig
    
    export KUBECONFIG=~/kubeconfig
    
    git config --global user.email  "user.name@gmail.com"
    
    git config --global user.name "userName"
  2. jxがどのOCIリソースを使うのかわかるよう、oci configファイルを構成します。CLIはこの時点ではインストールされません(実行中にインストールされます)。
    mkdir ~/.oci
    vi ~/.oci/config
    vi ~/.oci/oci_api_key.pem
    chmod 600 ~/.oci/config ~/.oci/oci_api_key.pem
  3. kubeconfig ファイルをエクスポートします。
    export KUBECONFIG=~/kubeconfig
  4. まだインストールしていない場合は、Gitをインストールします。
    sudo yum install git -y
  5. kubectlをインストールします。
    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
    chmod +x ./kubectl
    sudo mv ./kubectl /usr/local/bin/kubectl
  6. jxコマンドラインツールをインストールします。Linux以外のOSにインストールする場合、以下のインストール手順を確認してください。
    Get jx
    https://jenkins-x.io/getting-started/install/
    curl -L https://github.com/jenkins-x/jx/releases/download/v1.3.52/jx-linux-amd64.tar.gz | tar xzv
    sudo mv jx /usr/local/bin
  7. Helmクライアントをインストールし、すでにOKEクラスタにHelmサーバのtillerがインストールされていれば、それと会話できるようにします。
    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz
    tar -xvf helm-v2.9.1-linux-amd64.tar.gz
    cp linux-amd64/helm /usr/local/bin/
    helm init
  8. jxを使ってJenkins Xをインストールします。
    jx install --provider=oke
    インストールには数分かかります。この間に、GitHubのユーザー名のような必要なパラメータを設定できます。インストール完了後、2個のパイプライン(stagingとproduction)がJenkinsダッシュボード上に生成され、コードがGitHubにチェックインされます。


Other Jenkins X Options

ここまでで、Jenkins XをOKE上で実行するためのjx createやjx installコマンドを見てきました。任意の言語でプロジェクトを素早く立ち上げたり(jxは多言語の統合に対応しています)、パイプラインを構築したりするのが簡単になるようなjxコマンドがいくつかあります。

既存のプロジェクトで以下のコマンドを実行すると、いま取り組んでいるプロジェクトの種類を迅速にjxコマンドが検知します(例えば、Spring BootとかJHipsterとか、といった具合です)
jx import <app_name>
以下のアクションも実行します。
  • ビルドパイプラインの作成
  • (GirHubの資格証明を使い)GitHubのようなリモートのGitサービスにプロジェクトの設定と、必要なWebhookの作成
  • Helm ChartやMonocularといったKubernetes固有のツールのインストール
  • 最終的にビルドを実行して、ステージング環境にデプロイ
この時点で何も問題ないようでしたら、以下のコマンドを使ってこのビルドを本番環境に移行できます。
jx promote --env production --version 1.0.1 <app_name>
既存のプロジェクトがない場合、組み込みのCI/CD(jxコマンドを利用)を使ってプロジェクトを立ち上げるなら、(再度ですが)jx createを使うのが最も簡単ですが、例えばSpring Bootアプリケーションを作成したい場合、生成されたコードをGitリポジトリにインポートし、JenkinsをCI/CDで利用し、以下のコマンドを実行します。
jx create spring [flags]
このコマンドは以下の操作を実行します。
  • デフォルトの新しいSpring Bootアプリケーションを作成
  • コードをGitリポジトリにチェックイン
  • リモートのGitリポジトリ(GitHubなど)にコードをプッシュ
  • Dockerfile、jenkinsfile、Helm Chartのdefaultを追加
  • ビルドを実行し、staging環境にデプロイ

More Information

[Integration, Cloud] API-Key Based Authentication: Quickly and Easily

原文はこちら。
https://blogs.oracle.com/integration/api-key-based-authentication%3a-quickly-and-easily

API Keyベースの認証はAPIへのセキュアなアクセスを提供するシンプルな方法です。この認証は以下の手順を踏みます。
  1. (前提条件)ユーザーはサービスポータルにログインし、API Keyを生成する
  2. API Keyはクライアントアプリケーションと共有されている
  3. クライアントアプリケーションはAPI Keyを使ってリソースへのリクエストを作成する
下図はAPIキー・ベース認証で必要な手順を図示したものです。API KeyはクライアントはAPI呼び出し時に使うシンプルなトークンです。


How to invoke a REST API protected with an API-Key using Oracle Integration Cloud?

Oracle REST Adapterは外部RESTful APIを利用するための包括的な方法を提供しており、保護されたAPIのアクセスのためのセキュリティポリシーを指定するために利用可能な、再利用可能な接続を提供します。

API Keyで保護されたAPIを利用する場合、統合の開発者はAPIキー・ベース認証セキュリティポリシーを選択して統合作成を進めていきます。

接続のダイアログで、[セキュリティの構成]をクリックし、[APIキー・ベース認証]セキュリティポリシーを選択します。


APIキーを指定します。APIキー発見の手順はIntegration Cloudの範囲外です。


Integration CloudにAPIキーをリクエストと共に渡す方法を指定します。

APIキーの用途では、Oracle REST AdapterがAPIキーを呼び出し対象のサービスにアクセスするためにAPIキーを渡す方法を記載します。

REST Adapterを使って、ヘッダーやクエリ文字列としてAPIキーを渡すことができます。
APIキーの用途説明記述例
-H Authorization: Bearer ${api-key}保護されたリソースへアクセスするため、実行時にAuthorization ヘッダーとしてAPIキーを渡す。-H
Authorization: Bearer AASDFADADX
-H X-ApiKey: ${api-key}保護されたリソースへアクセスするため、実行時にX-ApiKeyと呼ばれるカスタムヘッダーとしてAPIキーを渡す。-H
X-ApiKey: AASDFADADX
?key=${api-key}保護されたリソースへアクセスするため、実行時にクエリ文字列としてAPIキーを渡す。http://someapi.com/employee? key=ASDFADAX

APIキーの用途には様々ありますが、デフォルトでは、REST AdpaterはAuthorizationヘッダーとしてAPIキーを渡します。
-H Authorization: Bearer ${api-key}
${api-key} の値にAPIキーを代入し、Authorizatinoヘッダーとしてエンドポイント・リクエストと共に送信します。
構成が完了すると、ユーザーはテスト*した上で保存して接続は完成です。他の接続と同様、この接続を統合フロー内で利用できます。リクエストを上記のように送信しながら、APIキーを自動的にエンドポイントに渡します。

注意: APIキーを接続内で更新すると、変更は自動的に全てのデプロイ済みの統合に反映されるため、統合フローのアップデートや再デプロイは必要ありません。

APIキーは簡単に利用できますが、欠点もあります。よく知られている点として、APIキーは手作業で生成されます。キーの期限が切れたり取り消された場合、ユーザーは手作業でサービスポータルに戻って新しいAPIキーを生成し、その後Oracle Integration Cloud内で更新する必要があります。これは連続性に影響を与える可能性があるため、注意する必要があります。HTTPサービスのほとんどはOAuth認可フレームワークをリソース保護に利用しています。今後、Oracle Integration Cloudを使ったOAuthで保護されたサービスへのアクセス方法をご紹介する予定にしています。

* テスト接続が成功してもAPIキーを検証しませんので、セキュリティポリシー内でAPIキーを利用する前に、統合の開発者はキーの検証をしておくことが重要です。

[JavaScript, Database] node-oracledb 3.0 Introduces SODA Document Storage

原文はこちら。
https://blogs.oracle.com/opal/node-oracledb-30-introduces-soda-document-storage

Release announcement:

Node-oracledb 3.0.0(Oracle DatabaseへアクセスするためのNode.js用モジュール)がnpmからご利用いただけるようになりました。
node-oracledb version 3.0
https://www.npmjs.com/package/oracledb

Top features:

  • Simple Oracle Document Access (SODA) (プレビュー)
  • 接続プールの廃棄
  • Callタイムアウト
Node-oracledb 3がリリースされました。このリリースではいくつかのOracle DatabaseおよびOracle Client 18cの機能をサポートしています。
以前のバージョンのように、node-oracledb 3はOracle Clientライブラリ11.2以降と組み合わせて利用できますので、クライアントバージョンに依存しますが、Oracle Database 9.2以後と接続できるようになります。ただ、Oracle Client 18.3ライブラリを使ってOracle Database 18.3と接続している場合のみ、最新のすばらしい一連のOracle Databaseの機能を利用できます。
node-oracledb 3.0でのトピックをご紹介しましょう。
  • Oracle Simple Document Access (SODA) のサポート:標準のリレーショナルアクセスモデルに加わったのが、Oracle SODAの新しいAPIです。例を使って後で説明します。
  • pool.close() の新しい引数drainTimeを使うと、指定した秒数が経過したらプールを強制的にクローズできます。この機能はDanilo Silvaの貢献によるものです。
    pool.close()
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#poolclose
    プールを指定したdrainTimeでクローズすると、後続のgetConnection()の呼び出しは失敗しますが、現在利用している接続は引き続き機能し続けます。これにより、コードの完了と未解決のトランザクションのコミットが可能になります。接続が使用されていない場合、またはドレイン時間到達時のいずれか最初に発生したタイミングで、プールとすべての接続を強制的にクローズします。

    「強制的にクローズ」という言葉は厳しく思われますが、実際には、ユーザーは接続プールがクローズ中、もしくはすでにクローズされているという明確なメッセージを得るため、ドレーン時間によってアプリケーションの正常終了が可能ですし、タイムアウトを待たずにデータベース側のセッションをきれいに解放することができます。drainTimeはゼロにすることもできるので、すべてのセッションを即座に終了できます。これは、データベースにとって都合よいようにアプリケーションを終了したいときに便利です。
  • 事前構築済みのnode-oracledbバイナリのインストールは、基本的なプロキシ認証のサポートによって少し楽になりました。また、プロキシ環境変数が設定されていない場合、インストール時に 'npm config'プロキシ値を使用するようになりました。これらの変更はCemre Menguの貢献によるものです。
  • 長時間実行されているデータベース呼び出しを中断するconnection.callTimeoutプロパティを追加しました。これは、Oracle Databaseのバージョンに関係なく、node-oracledb 3とOracle Clientライブラリのバージョン18.1以降を組み合わせて使用している場合に使用できます。
    connection.callTimeout
    https://oracle.github.io/node-oracledb/doc/api.html#propconncalltimeout
    呼び出しタイムアウトは制御不能なSQLやPL/SQL文の実行を防止する上で有用なものです。背景として、node-oracledbの実行の下にあるメインコード層はOracle Call Interfaceで、このAPIはOracle Databaseへの全てのネットワーク接続を処理します。node-oracledbが各OCI関数を呼び出すと、ゼロ回以上のDatabaseとのやりとり、つまりデータベースの呼び出しと戻ってくるレスポンスの取得というが発生します。

    callTimeout値は、各ラウンドトリップに個別に適用され、すべてのラウンドトリップの合計に適用されるわけではありません。各ラウンドトリップの完了前または終了後のnode-oracledbでの処理時間は対象外です。
    • とある1回のラウンドトリップの開始から、当該ラウンドトリップの完了までの時間がcallTimeoutミリ秒を超える場合、オペレーションを停止して、エラーを返します。
    • node-oracleledbのオペレーションで複数回のラウンドトリップが必要で、各ラウンドトリップがcallTimeoutミリ秒より短い時間の場合、すべてのラウンドトリップの合計がcallTimeoutを超えていても、タイムアウトは発生しません。
    • ラウンドトリップの必要がない場合、オペレーションは中断されません。
    callTimeoutミリ秒を超過すると、node-oracledbは内部接続状態をクリーンアップしようとします。このクリーンアップには、別のcallTimeoutミリ秒が適用されます。
  • クリーンアップが成功した場合、以下のエラーメッセージが返りますが、アプリケーションは引き続き接続を利用できます。
    "DPI-1067: call timeout of N ms exceeded with ORA-XXX"
    callTimeoutの値が小さい場合、追加のcallTimeout期間内に接続のクリーンアップが正常に完了しないことがあります。 この場合、ORA-3114が戻され、接続は使用できなくなり、接続を閉じる必要があります。
  • Windowsの場合、node-oracledbは、まず 'node_modules\oracledb\build\Release' ディレクトリからOracle Clientライブラリをロードしようとします。その後、標準のWindowsライブラリディレクトリ検索、つまり環境変数PATHで定義されたディレクトリからロードしようとします。

    この新機能は、Windowsにアプリケーションをバンドルし、Oracle Instant Clientを含める場合に便利です。つまり、クライアントライブラリを 'node_modules\oracledb\build\Release' ディレクトリに置くことでPATHの設定が不要になり、PATHを変更するユーザーを心配する必要がなくなり、PATHに複数のバージョンのOracle Clientライブラリがあっても心配する必要がないからです。
  • poolPingInterval機能は、Oracle Clientライブラリ12.2以降で接続プールを使用している場合に「再有効化」されています。ネットワークが切断されたかどうかを確認するのにOracle Clientの内部チェックが非常に効率的ゆえ、以前はこれらのバージョンでは意図的に有効になっていませんでした。しかし、データベース・セッション・リソース制限(例えば、使用時にORA-02396が返される)を超えたり、DBAによって明示的にクローズ(たとえば、ORA-00028が返される)されたりしたために利用不可になった接続は、内部チェックでは識別できません。ここで、poolPingIntervalが役に立ちます。
    oracledb.poolPingInterval
    https://oracle.github.io/node-oracledb/doc/api.html#propdbpoolpinginterval
    この変更により、アプリの可用性は高まるように見えますが、欠点もあります。アプリが黙って再接続している可能性がありますし、大きなプールを再構築する必要がある場合は、接続ストームに気付かない可能性があります。AWRレポートをチェックして接続が頻繁に発生しているかどうかを監視し、アイドル・セッションを終了しないようにネットワークおよびDBA管理者と協力して作業する必要があります。
その他の変更や機能改善は変更履歴をご覧ください。
Change Log
https://github.com/oracle/node-oracledb/blob/master/CHANGELOG.md
といいつつ、SODAについて説明をしますので、是非この後もお読みください。

Simple Oracle Document Access (SODA) in node-oracledb

Oracle Simple Document Access(SODA)はNoSQLスタイルのAPIのセットで、SQLを知らなくても、Oracle Databaseにドキュメント(特にJSON)のコレクションを作成および格納したり、取得や問合せを実行できます。Oracle Database 18.3およびOracle Client 18.3以上を使用している場合、node-oracledb 3でSODAサポートを利用できます。SODA APIは、Python、C、Java、PL/SQL、RESTで利用できるため、幅広くアクセスできるため、きっとお手元のデータツールキットの中でも有用なツールとなることでしょう。現在、node-oracledb 3 SODA APIは「プレビュー」扱いですが、Oracle Clientライブラリの将来のバージョンで変更される予定です。
node-oracledbのクラス図から、リレーショナルの世界とSODAの世界の分離がわかると思います。

現実には、SODAはOracle Databaseの表に基づいているので、セキュアで効率的なストレージ・ソリューションを提供します。これらの表にはSQLでアクセスできますが、ほとんどその必要はありません。それが必要なのは、レポート作成のための分析などの高度なOracle Database機能を使う場合だけでしょう。
代わりに、新しいクラスとメソッドを使います。DBAがSODA_APP権限を付与すると、その中にコレクションを作成したり、ドキュメント(JSONなど)を格納したりできます。いくつかの基本的なサンプルをご紹介します。
// Create the parent object for SODA.
soda = await connection.getSodaDatabase();

// Create a new SODA collection, if it doesn't exist.
// This will open an existing collection, if the name is already in use.
collection = await soda.createCollection("mycollection");

// Insert a document.
// A system generated key is created by default.
content = {name: "Matilda", address: {city: "Melbourne"}};
doc = await collection.insertOneAndGet(content);
key = doc.key;
console.log("The key of the new SODA document is: ", key);
キー・ルックアップや検索を使ってドキュメントを取得できます。キー・ルックアップは簡単です。
// Fetch the document back
doc = await collection.find().key(key).getOne(); // A SodaDocument
content = doc.getContent();                      // A JavaScript object
console.log('Retrieved SODA document as an object:');
console.log(content);
JSONに変換可能なドキュメントの場合、文字列として取得できます。
content = doc.getContentAsString();              // A JSON string
console.log('Retrieved SODA document as a string:');
console.log(content);
メソッドfind()はオペレーション・ビルダで順々に制限基準を設定できるので、一連のドキュメントの個数を減らした後に、getOne()getDocuments()count()などの終端メソッドが作用します。
JSONドキュメントでは、完全なフィルタリング仕様言語を使用してQBE(Query-by-Example)でドキュメントを検索できます。 以下は簡単な例です。
// Find all documents with city names starting with 'S'
documents = await collection.find()
  .filter({"address.city": {"$like": "S%"}})
  .getDocuments();

for (let i = 0; i < documents.length; i++) {
  content = documents[i].getContent();
  console.log('  city is: ', content.address.city);
}
実行可能なサンプルはsoda1.jsにあります。
soda1.js
https://github.com/oracle/node-oracledb/tree/master/examples/soda1.js#L34
node-oracledbのマニュアルのSODAのセクションとIntroduction to Simple Oracle Document Access(SODA)のマニュアルで、そのパワーとシンプルさを確認してください。
Simple Oracle Document Access (SODA)
https://oracle.github.io/node-oracledb/doc/api.html#sodaoverview
Oracle® Database Simple Oracle Document Access (SODA)の概要 18c
SODAの概要
https://docs.oracle.com/cd/E96517_01/adsdi/overview-soda.html#GUID-BE42F8D3-B86B-43B4-B2A3-5760A4DF79FBOracle® Database Introduction to Simple Oracle Document Access (SODA) 18c
Overview of SODA
https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-BE42F8D3-B86B-43B4-B2A3-5760A4DF79FB
まだOracle Database 18.3の環境をお持ちではありませんか?なら、こちらからどうぞ。
Oracle Database Software Downloads
https://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html
もしくは旧バージョンのOracle DatabaseでのJSONの利用にご興味があれば、こちらをどうぞ。
So you want to use JSON in Oracle Database with Node.js?
https://blogs.oracle.com/opal/so-you-want-to-use-json-in-oracle-database-with-nodejs

Summary

あなたの開発体験をより良いものにするために、node-oracledbに重要な機能を引き続き導入していきます。Wishlistにたくさん詰まっているため、引き続き作業を続けます。コミュニティからの貢献ははいつでも歓迎します。そして、node-oracledbの今リリースおよび以前のリリースの改善を手助けしてくれた方々に感謝いたします。

Resources