2011年12月7日水曜日

SimpleModelerServiceのアーキテクチャ

昨日公開したXMind→クラス図変換サービスは、g3上に構築したSimpleModelerServiceというRESTサービスです。
このRESTサービスはScalaでプログラミングし、WAR形式にパッケージングしたものをGlassFish上で動作させています。
Java系のPaaS標準コンテナは、WAR形式をJavaEEのWebプロファイル+αを動作させるものになると予想されるので、この環境をScala&自作フレームワークで試してみるというという目的もありました。

SimpleModelerServiceは以下の4つのモジュールから構成されています。

Goldenport
アプリケーションフレームワーク
g3
クラウドアプリケーションフレームワーク
SimpleModeler
モデルコンパイラ
SimpleModelerService
SimpleModelerサービス

SimpleModelerServiceが最上位にあるクラウドアプリケーションの本体で、g3上に構築されています。SimpleModelerServiceはgoldenport上に構築されたスタンドアロンアプリケーションであるSimpleModelerをRESTサービス化します。

SimpleModelerServiceの開発規模は以下の表になります。Scalaが約121.6Ks、Javaが約10.8Ksです。Scalaのコーディング量が100Kステップを超えてきておりちょっと感慨深いものがあります。

開発規模
モジュールScala(Ks)Java(Ks)
Goldenport16.89.1
g322.61.7
SimpleModeler82.1N/A
SimpleModelerService0.1N/A

SimpleModelerService on g3

SimpleModelerServiceでは、クラウドアプリケーション用フレームワークとして開発してきたg3を実応用に初めて適用することができました。

g3はScala DSLでアプリケーションを記述しますが、SimpleModelerServiceは以下のものになります。

class SimpleModelerService extends G3Application {
  title = "SimpleModeler"
  summary = 
SimpleModeler service produces various artifacts from a SimpleModeling model.
port("/diagram", Description( "Diagram", "SimpleModeler Diagram Service",
SimpleModeler diagram service produces a class diagram from a mindmap modeled by MindmapModeling.
, Schema( (Symbol("source.package"), XString, MZeroOne), ('_1, XBase64Binary))) ) agentpf { case p: Post => Post("diagram", p) } invoke('sm) goldenport('sm, SimpleModelerDescriptor) }

port("/diagram")はHTTPリクエストを受け取るポートを指定しています。
URIの断片"/diagram"にマッチしたHTTPリクエストがこのポートで受信され、パイプラインで以下の処理が実行されていきます。

  1. agentpfでPostリクエストを加工するPartialFunctionを実行。
  2. invokeでチャネルsmを呼出し。

その下にあるgoldenport('sm, SimpleModelerDescriptor)は、チャネルsmをGoldenportアプリケーションSimpleModelerに割り当てる設定です。SimpleModelerのGoldenport DSLであるSimpleModelerDescriptorを指定しています。

port("/diagram")からinvokeでこのsmチャネル経由でSimpleModelerが実行され、その実行結果がport("/diagram")の実行結果としてクライアントに返されます。

HTTPのプロトコル処理、FormやJSON、AtomPub, MIMEといったデータ入出力、ファイルのアップロード処理はg3フレームワークが行います。アプリケーションは、GetやPostといったメッセージに対する関数型的な転換処理の連鎖として、アプリケーションロジックを記述することができます。また、Goldenport上に構築したスタンドアロンアプリケーションは、シームレスに接続できるようになっており、ほぼそのままRESTサービス化することができます。

SimpleModeler on Goldenport

モデルコンパイラはアプリケーションフレームワークGoldenport上に構築しています。そのアーキテクチャを定義するDSLが以下のSimpleModelerDescriptorです。

class SimpleModelerDescriptor extends GApplicationDescriptor {
  name = "SimpleModeler"
  version = "0.3.0"
  version_build = "20111206"
  copyright_years = "2008-2011"
  copyright_owner = "ASAMI, Tomoharu"
  command_name = "sm"
  //
  classpath("target/classes")
  importers(ScalaDslImporter)
  entities(CsvEntity, XMindEntity, OpmlEntity, ExcelTableEntity, 
      OrgmodeEntity, YamlEntity)
  services(ProjectRealmGeneratorService,
    ImportService,
    ConvertService,
    HtmlRealmGeneratorService,
//    JavaRealmGeneratorService,
    GrailsRealmGeneratorService,
    GaeRealmGeneratorService,
    GaeoRealmGeneratorService,
    GaeJavaRealmGeneratorService,
    AndroidGeneratorService,
    G3GeneratorService,
    AsakusaGeneratorService,
    DiagramGeneratorService)
}

SimpleModelerDescriptorでは概ね以下のような定義を行っています。

  • importersで外部データの移入器としてScalaDslImporterを指定。
  • entitiesでCsvEntityやXMindEntityなどを指定。サフィックスがcsvやxmlになっているファイルを入力すると、自動的にCSVEntityやXMindEntityに変換される。
  • servicesでDiagramGeneratorServiceやAndroidGeneratorServiceなどを指定。パラメタにより自動的に適合するサービスが起動される。

Goldenportが外部入出力のもろもろをハンドリングしてくれるので、アプリケーションロジックの記述に専念することができます。g3を併用することでRESTサービスまでシームレスに接続できるようになりました。

ScalaとDSL

DSLの用途は大きく(1)モデルなどの静的な情報を記述、(2)フレームワークのAPIを記述、の2つに分けられます。

SimpleModelerがモデル記述に使っているScala DSLは前者の例です。

一方、本記事で取り上げたSimpleModelerService(g3)、SimpleModeler(Goldenport)は後者の例です。SimplModeler(Goldenport)のDSLは、Javaでも何とか実現できそうですが、SimpleModelerServiceのDSLはJavaではこのような記述は難しく、DSLを得意とするScalaの美点がよく出ています。

Scalaは元々、JavaでのDSL実現に限界を感じていたため、DSL用の言語として採用したのですが、十分満足できる結果を得られました。Scalaで100K超のコーディングを行った事になりますが、Javaと比べてプログラミングが圧倒的に楽ということも体感できました。

Goldenportやg3のようなDSLベースのAPIを持つフレームワークやコンポーネントがこれからどんどん出てくることが予想されるので、Scalaプログラミングの生産性はますます向上してくることになるでしょう。また、メニーコア時代の並行プログラミングは関数型言語を中心に広がっていきそうです。今回確認できたようにGlassFishのようなJava用のクラウドコンテナ(の候補)にもまったくシームレスに載せることができるのは、Javaとの互換性を軸に据えているScalaならではです。色々考えていくとScalaはかなり便利な言語で、クラウドアプリケーション向けプログラミング言語の最右翼かなと実感しています。

0 件のコメント:

コメントを投稿