Mule ESB 3.6起動
Mule 3.7での同エントリを書きました。
Mule ESB 3.6をしばらく触ってみようと思います。 環境はOSX 10.10.4です。
Mule ESB 3.6ダウンロード
今回はMule Community Editionでできることを調査しようと思います。 でもマニュアルにあるMule CEのダウンロードのリンクから移動しても、このEnterprise版のダウンロードページに飛ばされてしまいます。要確認だけど、取りあえず、こちらに含まれるStandaloneだけを使います。
Muleの起動
mmc-distribution-mule-console-bundle-3.6.1.zip
を解凍します。
MMCなども入っていますが、Runtimeモジュールのbinフォルダに移動します。
$ cd mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/bin
起動コマンドを実行します。
$ ./mule
起動ログ
いろんなソフトウェアをやっているとログは読み物だなと、思います。 ログを根気よく読むとソフトウェアが何をやっているのかが分かる。
$ ./mule MULE_HOME is set to /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1 Running in console (foreground) mode by default, use Ctrl-C to exit... MULE_HOME is set to /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1 Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 Running Mule Enterprise Edition... --> Wrapper Started as Console Java Service Wrapper Standard Edition 32-bit 3.5.19 Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved. http://wrapper.tanukisoftware.com Licensed to mulesoft.com for Mule ESB Enterprise Edition Launching a JVM... Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 Valid license key --> Evaluation = true, Expiration Date = Mon Aug 03 00:00:00 JST 2015, Contact Name = MuleSource Support, Contact Email Address = support@mulesource.com, Contact Telephone = support@mulesource.com, Contact Company = MuleSource, Contact Country = US, Entitlements = Starting the Mule Container... WrapperManager: Initializing... INFO 2015-07-04 06:56:00,050 [WrapperListener_start_runner] org.mule.module.launcher.MuleContainer: ********************************************************************** * Mule ESB and Integration Platform * * Version: 3.6.1 Build: 0758df2b * * MuleSoft, Inc. * * For more information go to * * http://www.mulesoft.com/mule-esb-enterprise * * * * Server started: 15/07/04 6:56 * * JDK: 1.7.0_71 (mixed mode) * * OS: Mac OS X (10.10.4, x86_64) * * Host: Ryohei-no-MacBook-Pro.local (192.168.11.5) * ********************************************************************** INFO 2015-07-04 06:56:00,089 [WrapperListener_start_runner] org.mule.module.launcher.coreextension.DefaultMuleCoreExtensionManager: Initializing core extensions INFO 2015-07-04 06:56:00,125 [WrapperListener_start_runner] com.mulesoft.mule.cluster.hazelcast.config.ClusterTicketFileLoader: /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/.mule/mule-cluster.properties (No such file or directory) WARN 2015-07-04 06:56:00,131 [WrapperListener_start_runner] com.mulesoft.mule.cluster.boot.ClusterCoreExtension: No cluster ID was specified -- High Availability will be disabled: INFO 2015-07-04 06:56:00,250 [WrapperListener_start_runner] com.mulesoft.mule.plugin.manager.MulePluginManager: Registering plugin: mule-plugin-debugger-3.6.0-RC1 INFO 2015-07-04 06:56:00,274 [WrapperListener_start_runner] org.mule.lifecycle.AbstractLifecycleManager: Initialising: 'Mule Agent Core Extension'. Object is: AgentCoreExtension INFO 2015-07-04 06:56:00,453 [WrapperListener_start_runner] org.mule.lifecycle.AbstractLifecycleManager: Initialising RegistryBroker WARN 2015-07-04 06:56:00,721 [WrapperListener_start_runner] org.mule.module.ognl.expression.OgnlExpressionEvaluator: OGNL module is deprecated and will be removed in Mule 4.0. Use MEL expressions instead. INFO 2015-07-04 06:56:01,261 [WrapperListener_start_runner] org.mule.config.processors.DecoratingAnnotatedServiceProcessor: org.mule.config.AnnotationsParserFactory implementation not found in registry, annotations not enabled INFO 2015-07-04 06:56:01,863 [WrapperListener_start_runner] org.mule.util.journal.TransactionJournal: Using files for tx logs /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-tx-log/tx1.log and /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-tx-log/tx2.log INFO 2015-07-04 06:56:01,883 [WrapperListener_start_runner] org.mule.util.journal.TransactionJournal: Using files for tx logs /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-xa-tx-log/tx1.log and /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-xa-tx-log/tx2.log INFO 2015-07-04 06:56:01,885 [WrapperListener_start_runner] org.mule.util.journal.TransactionJournal: Using files for tx logs /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-tx-log/tx1.log and /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-tx-log/tx2.log INFO 2015-07-04 06:56:01,886 [WrapperListener_start_runner] org.mule.util.journal.TransactionJournal: Using files for tx logs /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-xa-tx-log/tx1.log and /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/./.mule/.agent/queue-xa-tx-log/tx2.log INFO 2015-07-04 06:56:01,945 [WrapperListener_start_runner] org.mule.lifecycle.AbstractLifecycleManager: Initialising model: _muleSystemModel INFO 2015-07-04 06:56:02,113 [WrapperListener_start_runner] org.mule.module.launcher.coreextension.DefaultMuleCoreExtensionManager: Starting core extensions INFO 2015-07-04 06:56:02,113 [WrapperListener_start_runner] org.mule.lifecycle.AbstractLifecycleManager: Starting: 'Mule Agent Core Extension'. Object is: AgentCoreExtension INFO 2015-07-04 06:56:02,114 [WrapperListener_start_runner] org.mule.util.queue.QueueXaResourceManager: Starting ResourceManager INFO 2015-07-04 06:56:02,114 [WrapperListener_start_runner] org.mule.util.queue.QueueXaResourceManager: Started ResourceManager INFO 2015-07-04 06:56:02,128 [WrapperListener_start_runner] org.mule.modules.oauth2.provider.agents.DefaultSplashScreenAgent: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + DevKit Extensions (0) used in this application + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2015-07-04 06:56:02,129 [WrapperListener_start_runner] org.mule.lifecycle.AbstractLifecycleManager: Starting model: _muleSystemModel INFO 2015-07-04 06:56:02,137 [WrapperListener_start_runner] org.mule.module.management.agent.WrapperManagerAgent: Mule is embedded in a container already launched by a wrapper.Duplicates will not be registered. Use the org.tanukisoftware.wrapper:type=WrapperManager MBean instead for control. INFO 2015-07-04 06:56:02,153 [WrapperListener_start_runner] org.mule.DefaultMuleContext: ********************************************************************** * Application: .agent * * OS encoding: /, Mule encoding: UTF-8 * * * * Agents Running: * * DevKit Extension Information * * Batch module default engine * * Clustering Agent * * JMX Agent * ********************************************************************** INFO 2015-07-04 06:56:02,158 [WrapperListener_start_runner] org.eclipse.jetty.server.Server: jetty-9.0.7.v20131107 INFO 2015-07-04 06:56:02,371 [WrapperListener_start_runner] /mmc-support: Initializing Spring root WebApplicationContext INFO 2015-07-04 06:56:02,371 [WrapperListener_start_runner] org.springframework.web.context.ContextLoader: Root WebApplicationContext: initialization started INFO 2015-07-04 06:56:02,515 [WrapperListener_start_runner] org.springframework.web.context.support.XmlWebApplicationContext: Refreshing Root WebApplicationContext: startup date [Sat Jul 04 06:56:02 JST 2015]; root of context hierarchy INFO 2015-07-04 06:56:03,163 [WrapperListener_start_runner] org.springframework.web.context.support.ServletContextAttributeExporter: Exported ServletContext attribute with name 'discoveryEngine' INFO 2015-07-04 06:56:03,472 [WrapperListener_start_runner] org.quartz.core.SchedulerSignalerImpl: Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl INFO 2015-07-04 06:56:03,473 [WrapperListener_start_runner] org.quartz.core.QuartzScheduler: Quartz Scheduler v.1.8.5 created. INFO 2015-07-04 06:56:03,475 [WrapperListener_start_runner] org.quartz.simpl.RAMJobStore: RAMJobStore initialized. INFO 2015-07-04 06:56:03,476 [WrapperListener_start_runner] org.quartz.core.QuartzScheduler: Scheduler meta-data: Quartz Scheduler (v1.8.5) 'scheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads. Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered. INFO 2015-07-04 06:56:03,477 [WrapperListener_start_runner] org.quartz.impl.StdSchedulerFactory: Quartz scheduler 'scheduler' initialized from an externally provided properties instance. INFO 2015-07-04 06:56:03,477 [WrapperListener_start_runner] org.quartz.impl.StdSchedulerFactory: Quartz scheduler version: 1.8.5 INFO 2015-07-04 06:56:03,479 [WrapperListener_start_runner] org.quartz.core.QuartzScheduler: JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@5e8db999 INFO 2015-07-04 06:56:03,555 [WrapperListener_start_runner] org.springframework.context.support.DefaultLifecycleProcessor: Starting beans in phase 2147483647 INFO 2015-07-04 06:56:03,555 [WrapperListener_start_runner] org.springframework.scheduling.quartz.SchedulerFactoryBean: Starting Quartz Scheduler now INFO 2015-07-04 06:56:03,556 [WrapperListener_start_runner] org.quartz.core.QuartzScheduler: Scheduler scheduler_$_NON_CLUSTERED started. INFO 2015-07-04 06:56:03,569 [WrapperListener_start_runner] org.springframework.web.context.ContextLoader: Root WebApplicationContext: initialization completed in 1197 ms INFO 2015-07-04 06:56:03,651 [WrapperListener_start_runner] /mmc-support: Initializing Spring FrameworkServlet 'api' INFO 2015-07-04 06:56:03,651 [WrapperListener_start_runner] org.springframework.web.servlet.DispatcherServlet: FrameworkServlet 'api': initialization started INFO 2015-07-04 06:56:03,657 [WrapperListener_start_runner] org.springframework.web.context.support.XmlWebApplicationContext: Refreshing WebApplicationContext for namespace 'api-servlet': startup date [Sat Jul 04 06:56:03 JST 2015]; parent: Root WebApplicationContext INFO 2015-07-04 06:56:03,900 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/muleContextService] onto handler '/v3/muleContextService' INFO 2015-07-04 06:56:03,901 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/muleConfigurationService] onto handler '/v3/muleConfigurationService' INFO 2015-07-04 06:56:03,901 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/wrapperManagerService] onto handler '/v3/wrapperManagerService' INFO 2015-07-04 06:56:03,901 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/auditService] onto handler '/v3/auditService' INFO 2015-07-04 06:56:03,901 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/flowService] onto handler '/v3/flowService' INFO 2015-07-04 06:56:03,902 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3_1/clusterNodeService] onto handler '/v3_1/clusterNodeService' INFO 2015-07-04 06:56:03,902 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/trackingService] onto handler '/v3/trackingService' INFO 2015-07-04 06:56:03,902 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/systemFileService] onto handler '/v1/systemFileService' INFO 2015-07-04 06:56:03,902 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/muleFileService] onto handler '/v1/muleFileService' INFO 2015-07-04 06:56:03,902 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/threadsService] onto handler '/v1/threadsService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/memoryService] onto handler '/v1/memoryService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/statusService] onto handler '/v3/statusService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/jmxService] onto handler '/v1/jmxService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/poolService] onto handler '/v3/poolService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/statisticsService] onto handler '/v1/statisticsService' INFO 2015-07-04 06:56:03,903 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/statisticsService] onto handler '/v3/statisticsService' INFO 2015-07-04 06:56:03,904 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/systemService] onto handler '/v3/systemService' INFO 2015-07-04 06:56:03,904 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/alertService] onto handler '/v1/alertService' INFO 2015-07-04 06:56:03,904 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v1/slaService] onto handler '/v1/slaService' INFO 2015-07-04 06:56:03,904 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/applicationService] onto handler '/v3/applicationService' INFO 2015-07-04 06:56:03,904 [WrapperListener_start_runner] org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: Mapped URL path [/v3/applicationLogService] onto handler '/v3/applicationLogService' INFO 2015-07-04 06:56:04,122 [WrapperListener_start_runner] org.springframework.web.servlet.DispatcherServlet: FrameworkServlet 'api': initialization completed in 471 ms INFO 2015-07-04 06:56:04,127 [WrapperListener_start_runner] /mmc-support: AgentServlet: Starting MMC Agent. INFO 2015-07-04 06:56:04,129 [WrapperListener_start_runner] /mmc-support: AgentServlet: Initialized com.mulesoft.mmc.agent.web.AgentServlet@f51d94d with ID c71a8cd9-dc7e-4750-bc51-d1faf204ceea INFO 2015-07-04 06:56:10,825 [WrapperListener_start_runner] org.eclipse.jetty.server.handler.ContextHandler: Started o.e.j.w.WebAppContext@2046bc37{/mmc-support,jar:file:/Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/lib/mule/mmc-agent-impl-3.6.1.jar!/mmc-support-app,AVAILABLE} INFO 2015-07-04 06:56:10,839 [WrapperListener_start_runner] org.eclipse.jetty.server.ServerConnector: Started ServerConnector@b094e09{HTTP/1.1}{0.0.0.0:7777} INFO 2015-07-04 06:56:10,862 [WrapperListener_start_runner] org.eclipse.jetty.server.ServerConnector: Stopped ServerConnector@b094e09{HTTP/1.1}{0.0.0.0:7777} INFO 2015-07-04 06:56:10,966 [WrapperListener_start_runner] org.eclipse.jetty.server.ServerConnector: Started ServerConnector@44e995bf{SSL-HTTP/1.1}{0.0.0.0:7777} INFO 2015-07-04 06:56:10,967 [WrapperListener_start_runner] com.mulesoft.mmc.agent.AgentCoreExtension: Mule Agent Core Extension listening on (0.0.0.0:7777) INFO 2015-07-04 06:56:10,972 [WrapperListener_start_runner] org.mule.module.launcher.DefaultArchiveDeployer: ================== New Exploded Artifact: default INFO 2015-07-04 06:56:10,980 [WrapperListener_start_runner] org.mule.module.launcher.MuleSharedDomainClassLoader: Using domain dir /Users/rsogo/work/mmc-distribution-mule-console-bundle-3.6.1/mule-enterprise-3.6.1/domains/default for domain default INFO 2015-07-04 06:56:11,077 [WrapperListener_start_runner] org.mule.module.launcher.MuleDeploymentService: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Started domain 'default' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2015-07-04 06:56:11,079 [WrapperListener_start_runner] org.mule.module.launcher.DefaultArchiveDeployer: ================== New Exploded Artifact: default INFO 2015-07-04 06:56:11,101 [WrapperListener_start_runner] org.mule.module.launcher.application.DefaultMuleApplication: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + New app 'default' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2015-07-04 06:56:12,140 [WrapperListener_start_runner] org.mule.module.launcher.MuleDeploymentService: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Started app 'default' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2015-07-04 06:56:12,192 [WrapperListener_start_runner] org.mule.module.launcher.DeploymentDirectoryWatcher: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Mule is up and kicking (every 5000ms) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2015-07-04 06:56:12,207 [WrapperListener_start_runner] org.mule.module.launcher.StartupSummaryDeploymentListener: ********************************************************************** * - - + DOMAIN + - - * - - + STATUS + - - * ********************************************************************** * default * DEPLOYED * ********************************************************************** ******************************************************************************************************* * - - + APPLICATION + - - * - - + DOMAIN + - - * - - + STATUS + - - * ******************************************************************************************************* * default * default * DEPLOYED * *******************************************************************************************************
Mule 3.5のセットアップとサンプルの実行
会社の方で公式ドキュメントして書くのだけど、ひとまずこちらに書いてみます。
目標は、取りあえずインストールして、実行してみるところまで。
インストール
使用可能な環境はここでチェック。OSはMuleがサポートしているJDKがサポートしていればOKっぽい。
http://www.mulesoft.org/documentation/display/current/Hardware+and+Software+Requirements
どんな構成にするか
デプロイモードを選択する。
http://www.mulesoft.org/documentation/display/current/Deployment+Scenarios
ここでいうデプロイメントとは、Mule自体の配置のこと。Mule上で動作するモジュールのデプロイメントではない。
MuleはAPサーバー上でも動かすことができるけど、基本はスタンドアローンでOK。
Mule Management Consoleって使うの?
http://www.mulesoft.org/documentation/display/current/Mule+Management+Console
いろいろな管理機能が提供される。Enterprise Editionが必要。
インストールの手順はこれの「Mule Community Runtime」のタブに従ってやればOK。基本、スタンドアローン構成ならZipを解凍するだけ。
http://www.mulesoft.org/documentation/display/current/Downloading+and+Launching+Mule+ESB+-+hid
export JAVA_HOME=/usr/java/jdk1.7.0_60/
- Muleセットアップ 解凍するだけ。まじ簡単。
bin/muleを実行で起動。終了するときはCtlr+C。
起動停止
$MULE_HOME\bin\mule.bat start|stop
起動オプションなんかは下記にまとまっている。
http://www.mulesoft.org/documentation/display/current/Starting+and+Stopping+Mule+ESB
自分で作ったモジュールを動かしてみよう
Anypont Studioを入れるとSampleが一緒に付いてくるから、それを実行してみましょう。
スタートページのOpen Sampleでサンプルの一覧が見られる。
まあ、最初はHelloWorldだろうと。
フロー定義の見た目はこんな感じ。 HTTPでリッスンして、文字列を返すだけのフロー。
取りあえず試すだけなら、Anypont Studioの中に埋め込みMuleが入っているのでプロジェクトを右クリックして、「Run AS-> Mule Application」でOK。
サーバー上のMuleへのデプロイは上記のURLの「Deploy on a Mule Enterprise Server」の通りにやればOK。
Anypont StudioでExportする
Muleへのデプロイ
Mule HOMEのappsフォルダにzipを置くだけ。 Muleがポーリングをしていて、しばらくするとzipが解凍されます。
[sogo@localhost mule-standalone-3.5.0]$ cd apps/
[sogo@localhost apps]$ ls
default default-anchor.txt
appsフォルダにエクスポートしたhello-world.zipを置くと・・・・
[sogo@localhost apps]$ cp ~/hello-world.zip .
[sogo@localhost apps]$ ls
default default-anchor.txt hello-world.zip
しばらくするとzipが展開されてデプロイされている。
[sogo@localhost apps]$ ls
default default-anchor.txt hello-world hello-world-anchor.txt
Muleのデプロイログ
同じタイミングでMule側のログには、サンプルアプリが置かれたことを検知して、インストールして起動した旨のログがでます。
INFO 2014-06-26 21:26:12,950 [Mule.app.deployer.monitor.1.thread.1] org.mule.module.launcher.ArtifactArchiveInstaller: Exploding a Mule artifact archive: file:/home/sogo/mule/mule-standalone-3.5.0/apps/hello-world.zip
INFO 2014-06-26 21:26:13,008 [Mule.app.deployer.monitor.1.thread.1] org.mule.module.launcher.application.DefaultMuleApplication:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ New app 'hello-world' +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO 2014-06-26 21:26:13,009 [Mule.app.deployer.monitor.1.thread.1] org.mule.module.launcher.log4j.ArtifactAwareRepositorySelector: Found logging config for application 'hello-world' at 'file:/home/sogo/mule/mule-standalone-3.5.0/conf/log4j.properties'
INFO 2014-06-26 21:26:15,796 [Mule.app.deployer.monitor.1.thread.1] org.mule.module.launcher.MuleDeploymentService:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Started app 'hello-world' +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
いやー簡単ですね。
RESTのMockテストにSoapUIを使うには
SoapUIはWebサービスのテストを便利にやるためのツールです。
SoapUIはWSDLからテストリクエストや、モックを自動生成してくれるのが非常に便利なんですが、RESTでも使えます。SOAPと違ってテストデータは自分で作らないといけないですが、テスト用のクライアントコードや、モックのコードを書かなくていいので便利です。
モックサービスの概要
SoapUIのモックサービスは、設定したポート番号でリクエストを待ち受け、クライアントに対して任意のレスポンスメッセージを返すことができる機能です。
モックサービスを使用することで、Webサービスの開発が完了していない場合でも、クライアントの動作確認や単体テストを実施することが可能です。
SoapUIの入手は下記のDownloadsからSoapUI Downloadを選択してください。
http://www.soapui.org/
REST用モックサービスの設定手順
4.レスポンスメッセージを設定
SOAPの場合と異なり、RESTの場合はファイルとしてテストデータを設定し、設定したDocrootディレクトリの下に配置します
$ pwd /Users/sogo/docroot $ cat test.json { "name":"Taro", "id":1 }
6.クライアントからリクエストを送信
テストしたいクライアントからリクエストを送信する。
このとき、URLをモックサービスのものに変更する必要があります。
http://<MockServcieを動かすホスト>:<Port設定値>/<Path設定値>/<Docrootに配置したテストファイル>
Docrootディレクトリにテストパターンごとのテストデータを用意しておけば便利ですね。
SoapUIについてはこのエントリにまとめています。
SOAP UIのTestSuite機能を使ったWebサービスのテスト自動化
SOAP UIはWebサービスを呼び出すことができるテストツールです。
前回はモックサービスの機能を使って、Webサービスがまだできてないタイミングでの、Webサービスの利用側のアプリのテストを効率的に行う方法を書きました。SOAP UIはフリー版が用意されています。有償版はレポーティング機能などが充実しているようです。
今回はSOAP UIのTestSuiteという機能を使って、JUnitのような感じでWebサービスのテストを自動的に行う方法です。
単体テストレベルだれば、xUnitを使ってプログラムレベルで確認するので良いと思います。ただ、機能テスト、結合テストまで行くと、SOAP UIの様なテストツールを使って、実際にテスト環境にデプロイされたWebサービスを自動で、何度も、テストできるのはすごいメリットだと思います。
早速準備。まず、新しいプロジェクトを作成します。
テストをしたいWebサービスのWSDLを選択して、"Create TestSuite"にチェックをします。これでTestSuiteが用意されますが後からでも追加できます。
画面左にTestSuiteの設定が管理されているツリーができています。
管理の大きさとしてはTestSuite>Test Case>Test Stepです。一連のテストのシナリオがTestCaseで、そのシナリオの中で実装されるアクションがStepくらいの感じで良いと思います。TestStepを右クリックして"Add Step"を選ぶとStepをどんどん追加していけます。
Assertionの種類はいろいろ事前に用意されています。
以下は、レスポンスメッセージ中に含まれる文字列をチェックしている例です。
文字列比較以外にもXPathやXQueryを使って確認したり、HTTPのレスポンスコードや、SOAP Faultかどうか、さらにはSLAとしてレスポンスタイムが何秒以内かを確認することまでできます。
さて、実際にテストを事項してみましょう。
この例では、テストを実行したけれど、Assertionで想定外の結果が発見されています。
さらに、エラーになったテストをクリックすると、更に詳細な結果を確認することができます。
もちろんJUnitのように一連のシナリオを連続で実行することもできるので、商品の登録、参照、削除といったシナリオを用意しておいて、自動でテストを流すこともできます。
今やっているプロジェクトでも、全部のケースを網羅するテストはSOAP UIでやる予定は無いのですが、よく使われる機能、クリティカルな機能は、SOAP UIのTestSuiteを使って、サーバにデプロイされる度に自動で実行するように計画しようとしています。
本ブログのSOA系のエントリをまとめました。
私は日本オラクルでコンサルティングに所属していて、SOAというキーワードで7年間ほど日本のプロジェクト現場で製品の導入方法論や、システム全体の分析・設計、運用・ガバナンスなどについてコンサルをやっていました。
もともとJavaのエンジニアだったので、アプリケーションサーバのチューニングや、トラブルシューティングなんかもやっていました。
ある日から担当している製品がOracle Application ServerからWebLogicに変わったり、Sunの買収にびっくりしたのが懐かしいです。
日本を代表する大企業のシステムを数多く担当させてもらい、優秀なプロジェクトメンバーの方々や、同僚と仕事ができて、本当にエンジニアとして幸せだったと思います。
2012年6月で日本オラクルを退社しましたので、振り返りも含めてSOA関連のエントリをまとめてみます。
ずいぶん昔の記事ですが、私のSOAに対する考え方です。
SOAが終わったのかどうか、に関する自分の考え
今でのこの考えは変わっていません。ことさらSOAという必要はなく、普通に機能の分析や、どこに何を配置するのかを1システムごとではなく全社的に考えられればそれで良いと思います。
とあるSOAのプロジェクトが終わったときに、現場でどのような苦労があったのか、またどのような気づきがあったのかを書いています。
SOA実装プロジェクトでの苦労と対策
SOA実装プロジェクトでの苦労と対策 その2
他のシステムとリアルタイムにやり取りしながら、ある処理を完結するというのはやはり、難易度は高いと思います。それは、技術的な面もありますし、うちが作ってないから〜という連携先の仕様がよく分からないというのもあります。
この苦労を味わうとガバナンスの重要性に気づきますよね。かってにAPIのインターフェイス変更するんじゃない!とか、うちのDBをどこか知らないシステムが参照してます!みたいな。
サービス化を利用者側のニーズ、サービス提供側のニーズ、どちらで始めるにしても、それぞれ超えないと行けない課題があります。
サービス化のインプリをどこから始めるか
データ統合、マスターデータ管理などは昔からどの企業も関心の高いテーマだと思います。データ統合のパターンごとに、サービスや、ESBを使ってどのようなことができるかを書いています。
SOAとデータベース(1)
SOAとデータベース(2)
SOAとデータベース(3)
この3つのエントリは再編集してOTNの記事にしてもらいました。
第1回 SOAと4つのソリューションパターンとその効果
第3回 SOAの4つの事例から見るデータマネジメントの本当
SOAP UIのMock Serviceを使った効率的なWebサービスのテスト
SOAP UI(http://www.soapui.org/)という便利なツールがありまして、5年くらい前から個人的にもよく使っており、いくつかのプロジェクトでも紹介して使ってもらっていますので、その紹介をしたいと思います。
SOAP UIの一番シンプルな使い方は、Webサービスに対して、SOAPメッセージを簡単に作ってリクエストを送ることができることです。今回は、一歩進んでMock Serviceという機能を使います。
Mock Serviceの必要性
SOAPやRESTなどのWebサービスを使うプロジェクトの場合、1つのWebアプリケーションの開発でやっていたテストと違う、気をつけなくてはいけない点がいくつかあります。
例えば、Webサービスを呼び出すために、Webサービス側ができあがるタイミングが依存する。
普通にやるとWebサービスができるまで、Webサービスのクライアントはテストすることができません。呼び出す先がいませんから当たり前ですね。
これは10年以上前のVBやC++でやっていたクライアント・サーバー型のアーキテクチャだったときも同じ課題があったんですが、解決策としてはサーバ側のモックを作ります。モックは中身は無いけど、リクエストを受け取って、適当なテスト用のレスポンスを返してくれるプログラムです。
SOAP UIのMock Serviceは、このモックを簡単に用意する機能です。
Mock Serviceの設定手順
SOAP UIの初期画面です。まずはテストしたいWebサービスのWSDLを入手しておいて、新規プロジェクトを作成します。
次にWSDLファイルを選択します。後で、WSDLからテストメッセージをある程度自動生成してくれます。
デフォルトではCreate Requestsにしかチェックが入っていませんが、Create Mock Serviceにもチェックを入れます。
テストしたいWebサービスのオペレーションを選択します。
Mock Serviceはここで設定したURLとポート番号でリクエストを待ち受けます。
次にテスト用のレスポンスメッセージをセットします。
WSDL(XSD)を元に、メッセージの枠は自動生成されるので、後は値のみをテストしたい内容に合わせて埋めていきます。
準備ができたら、Mock Serviceをスタートさせます。
通常、ここまででMock Serviceの準備は完了です。後は開発したクライアントから呼び出して動作確認や、テストを行ってください。
ここでは、テスト用のプログラムは無いので、SOAP UIのテスト用リクエストを送る機能を使って、動作確認しました。
左側のリクエストを送ると、右側のレスポンスにMock Serviceで設定したメッセージが返ってきているのが分かります。
ここで送ったリクエストはMock Serviceの画面の左側のリクエストメッセージのエリアに表示されて、後で確認することができます。
最後に、SOAP UIには、画面下部にHTTPのログを表示させる機能がありますので、トラブル時にはそちらを見て解析することができます。
SoapUIについてはこのエントリにまとめています。
SOAPとREST。SOAPは死んだのか
SOAP is Not Dead - It's Undead, a Zombie in the Enterpriseを読みました。
SOAPは死んでない、ゾンビだ。ということです。
自分自身はB2B、または巨大企業の社内システム間に関わることが多く、ほとんどSOAPです。
SOAP&WSDLの良いところは、ツールを使っての自動生成や、アノテーションからのWSDLの自動生成などにあると思います。つまり、厳密に仕様定義を行いツール(機械)が判別できるようにすることです。
一方、REST。
ここでいうRESTはいわゆるRESTFulとかではなく、プロトコルとしてのRESTだと思うのですが、シンプル、レイヤーとしてthinになります。
開発生産性でいうと、どっちでも変わらない。特にでかいプロジェクトでは、サービス呼び出しの部分なんかほんの一部なので誤差の範囲だと思います。
SOAPは面倒と言われますが、自動のためのツールとJavaにはかなり最適化されていると思うので、クラスからのWebサービス化や、WSDLをもとにクライアントを作るのは一瞬です。
SOAPでデメリットかなーと思うのは、、、
- SOAPは自動生成されたコードが多いので、何かあったときに追っかけていくのが面倒。
- SOAPの自動生成コードと、APサーバのライブラリとの相性を要チェック。APサーバが異なると動かない場合がある。もちろん普通の場合は大丈夫だけど、暗号化とか認証とかちょっと変わったことをやろうとするとある
これらはRESTを使い込んでいないので、実はRESTでもあるのかも知れないけれど
「Java による RESTful システム構築」 を読んでみようと思う。以下書評。
http://www.artonx.org/diary/20100810.html#p01
http://d.hatena.ne.jp/Yoshiori/20100906/1283762429