YellowfinのWebサービスを使ってダッシュボードを別アプリに組み込む


Yellowfinには外部システムと連携するための「Webサービス」が備わっています。
これを使えば御社の独自アプリにBI機能をお手軽アドオン！
ということで試してみます。

# Yellowfinの組み込み
別アプリケーションにYellowfinを組み込む方法はいくつかあります。

- JavaScript API
- Webサービス
- DashXML

これらのうち、最後のDashXMLは別の機会に譲ることにして、今回はJavaScript APIとWebサービスの二つの例を試してみます。ちなみにYellowfinのプレスリリースでは、DashXMLについて以下のように説明されています。

> DashXMLは、柔軟性の高いフレームワークであり、レポートやフィルター、セキュリティのようなBIプラットフォームの機能を公開するYellowfinのウェブサービスAPI経由で通信する一方で、アプリケーションデザイン、レイアウト、ユーザー対話性の面でも、自由に構築が可能です。

# 今回やること
Yellowfinのダッシュボードを、別に立てたTomcat上のアプリに組み込んで表示させます。
あえて絵に描いてみるとこんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116818/51451b2f-2f84-4164-0e62-9fb41fea29ad.png "image.png")

# JavaScript APIの場合
まずはJavaScript APIを使った方法から。

Yellowfinのダッシュボードやレポートといったコンテンツは個々にユニークなIDを持っています。
そして、そのIDをパタメータに持ったユニークなURLがあり、そのURLを使えば各コンテンツへリンクを張ることができます。
さらに、各コンテンツをWebページへ埋め込むための「埋め込みタグ」も用意されています。

この埋め込みタグをWebページの任意の箇所へ貼り付ければ、Yellowfinのダッシュボードやレポートを表示できるって寸法です。

埋め込みタグの取得はコンテンツの「共有」から可能です。

![tag.gif](https://qiita-image-store.s3.amazonaws.com/0/116818/433dc30a-d0eb-f083-8402-777af0a1acf5.gif "tag.gif")

ではこの埋め込みタグをコピペしましょう。以下がサンプルです。（見た目わかりやすく＆見栄えがするようにBootstrapを使っていますが、もちろん必須ではありません）

```html:sample.html

<html>
  <head>
    <meta charset="utf-8">
    <title>Yellowfin組み込みサンプル</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Hoge Systems</a>
        </div>
      </div>
    </nav>

    <div class="jumbotron">
      <div class="container">
        <h1>Hello, world!</h1>
        <p>これはサンプルのWebサイトです。</p>
      </div>
    </div>

    <div class="container">
      <script type="text/javascript" src="http://localhost:8080/JsAPI?dashUUID=1e68d9cc-fa5a-44e2-816d-782aa40ceeae"></script>
    </div>

  </body>
</html>
```

なお、コピペ元の埋め込みタグではYellowfinのポート番号が省略されていますので、貼り付けた後に適宜補完してください。

で、これを開けばYellowfinのダッシュボードが組み込まれている！……のですが、ちょっと残念なことに大抵の場合は以下のようなログイン画面が表示されてしまいます。

![login.png](https://qiita-image-store.s3.amazonaws.com/0/116818/a4e6da57-a0d2-a1dd-aff8-589b290d91d6.png "login.png")

この画面でログインしてから、ようやくダッシュボードが表示されます。

ゲストユーザーに公開されているコンテンツならログイン不要ですが、そうでなければログインを求められます。当然ですね。ログインせずに見えちゃったら逆に問題です。

Yellowfinへのログインセッションがブラウザに残っていればログイン画面は表示されないので、初回のみの煩わしさではあるのですが、やっぱり煩わしいことに違いはありません。これはもうJavaScript APIだけではどうしようもないです。[^1]

[^1]: URLのパラメータでIDとpassを渡す方法もあるのですが、セキュリティ上の観点からあまりおすすめできません。

# Webサービスの場合
ということで今回の本題であるWebサービスを使ってみましょう。やり方には以下の2パターンがあります。

- Yellowfinが提供しているクライアントライブラリを使う
- WSDL定義からスタブを生成して使用する

今回はお手軽に試すため前者の方法を取ります。

## ライブラリの配置
Webサービスのクライアントライブラリは\[Yellowfinのインストールディレクトリ\]/development/libにある「yfws-YYYYMMDD.jar」というファイルです。
このファイルをTomcatのクラスパスが通っている場所（WEB-INF/lib等）に置きます。

今回の構成の場合、このクライアントライブラリだけでは動作しません。依存関係にあるライブラリが他にも必要になります。ひとまとめにしておいてくれよ。。。と思いますが仕方ないのでそちらも準備します。
[Yellowfinのインストールディレクトリ]/appserver/webapps/ROOT/WEB-INF/libにある以下のファイルを、先ほどと同じ場所にコピーしてください。[^2]

- axis.jar
- commons-discovery.jar
- commons-logging-x.x.x.jar
- jasperreports-x.x.x.jar
- jaxrpc.jar
- log4j-x.x.x.jar
- wsdl4j-x.x.x.jar

[^2]: 手を抜くためにYellowfinに含まれているモノをコピーしています。本来は各地からきちんとダウンロードしてくるのが正しいです。

## サンプルコード

さて、いよいよWebサービスを使ったコードを書いてみます。

```jsp:sample.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ page import="com.hof.util.*, java.util.*, java.text.*" %>
<%@ page import="com.hof.web.form.*" %>
<%@ page import="com.hof.mi.web.service.*" %>
<%
     String host = "localhost";
     Integer port = 8080;
     String path = "/services/AdministrationService";
     String userid = [ユーザーID];
     String password = [パスワード];
     String uuid = "1e68d9cc-fa5a-44e2-816d-782aa40ceeae";

     AdministrationServiceResponse rs = null;
     AdministrationServiceRequest rsr = new AdministrationServiceRequest();
     AdministrationServiceService ts = new AdministrationServiceServiceLocator(host, port, path, false);
     AdministrationServiceSoapBindingStub rssbs = (AdministrationServiceSoapBindingStub) ts.getAdministrationService();

     rsr.setLoginId(userid);
     rsr.setPassword(password);
     rsr.setOrgId(new Integer(1));
     rsr.setFunction("LOGINUSER");

     AdministrationPerson ap = new AdministrationPerson();
     ap.setUserId(userid);
     ap.setPassword(password);
     rsr.setPerson(ap);

     rs = rssbs.remoteAdministrationCall(rsr);

     String token = "";

     if ("SUCCESS".equals(rs.getStatusCode()) ) {
	 	token = rs.getLoginSessionId();
     } else {
	        out.write("ログイン失敗");
		return;
     }
%>

<html>
  <head>
    <meta charset="utf-8">
    <title>Yellowfin組み込みサンプル</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Hoge Systems</a>
        </div>
      </div>
    </nav>

    <div class="jumbotron">
      <div class="container">
        <h1>Hello, world</h1>
        <p>これはサンプルのWebサイトです。</p>
      </div>
    </div>

    <div class="container">
      <script type="text/javascript" src="http://<%=host%>:<%=port%>/JsAPI?dashUUID=<%=uuid%>&token=<%=token%>"></script>
    </div>

  </body>
</html>
```

見てのとおり、後半部分は前出のJavaScript APIの場合とほぼ同じです。
唯一異なるのが埋め込みタグに「token=xxx...」という **シングルサインオントークン** を追加している点です。

つまりこのサンプルでは、前半部分でWebサービスを使ったシングルサインオンの処理を行い、そこで取得したトークンを埋め込みタグに追加してJavaScript APIを使ったダッシュボードの埋め込みを行っています。

処理の詳しい内容は[Yellowfinのオンラインマニュアル](http://wiki.yellowfinbi.jp/pages/viewpage.action?pageId=7275010)を参照してください。

このJSPを実行して以下の画面が表示されたら成功[^3]です。 お疲れ様でした。

[^3]: 上手くいかない場合の理由としては、ライブラリのコピーしたけどTomcatを再起動し忘れているとか、JSPで使用しているYellowfinユーザーのセッションが残っていて重複ログインになっているとかが考えられます。

![dash.png](https://qiita-image-store.s3.amazonaws.com/0/116818/246810ff-d09f-bf31-24f4-94a527f3b571.png "dash.png")

# まとめ
今回はシングルサインオンの処理を組み込むだけの簡単な例でしたが、Webサービスを使えばアプリにYellowfinをシームレスに統合することができます。

# 参考
[JavaScript API](http://wiki.yellowfinbi.jp/display/USER73/JavaScript+API)
[Webサービス](http://wiki.yellowfinbi.jp/pages/viewpage.action?pageId=7275009)
[管理サービス](http://wiki.yellowfinbi.jp/pages/viewpage.action?pageId=7275010)