まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

2017年08月

Node.js のアプリケーションで、以下のような処理を実装してみました:
 - 認証(ログイン)用の API には誰でもアクセスできる
 - 認証 API では ID とパスワードを与えて認証し、正しいユーザーにはトークンを発行する
 - 認証以外の主な API はこの発行されたトークンを使ってアクセスした時だけ実行を許可する
 - API 呼び出し時にトークンがなかったり、正しくなかった場合は実行せずにエラー


この仕組を実現するために JSON Web Tokens (以下 "JWT")を使いました:
https://jwt.io/

2017081400


JWT はオープンかつ Node.js ではスタンダードなトークンベースの認証ライブラリです。以下で紹介するサンプルでは Web フレームワークである Express や、POST データを扱う body-parser も合わせて使うので、まとめてインストールしておきます:
$ npm install express body-parser jsonwebtoken

これらのライブラリを使って以下のようなアプリケーションを作成します:
//. app.js

var express = require( 'express' );
var app = express();
var bodyParser = require( 'body-parser' );
var jwt = require( 'jsonwebtoken' );

//. アプリケーションサーバーの稼働ポート番号
var port = process.env.PORT || 8080

//. 任意のシークレット文字列を登録
app.set( 'superSecret', 'welovenodejs' );  //. 任意の文字列

app.use( bodyParser.urlencoded( { extended: false } ) );
app.use( bodyParser.json() );

//. ユーザー情報(本来は DB などに格納された情報を使う)
var users = [
  { name: 'user0', password: 'pass0', admin: true },
  { name: 'user1', password: 'pass1', admin: false },
  { name: 'user2', password: 'pass2', admin: false },
  { name: 'user3', password: 'pass3', admin: false }
];

//. ドキュメントルートへの GET は許可
app.get( '/', function( req, res ){
  res.send( 'Hello. The API is at http://localhost:' + port + '/api' );
});

//. API ROUTES
var apiRoutes = express.Router();

//. トークンなしでアクセスを許可する API を先に定義する

//. POST(http://localhost:8080/api/authenticate)
apiRoutes.post( '/authenticate', function( req, res ){
  for( var i = 0; i < users.length; i ++ ){
    if( users[i].name == req.body.name && users[i].password == req.body.password ){
      //. 認証したユーザーの情報を使ってトークンを生成
      var token= jwt.sign( users[i], app.get( 'superSecret' ), {
        expiresIn: '24h'
      });
      res.json( { success: true, message: 'Authentication successfully finished.', token: token } );
      return;
    }
  }

  res.json( { success: false, message: 'Authentication failed.' } );
  return;
});

//. ここより上で定義した API には認証フィルタはかけていない(そのまま使える) //. 認証フィルタ apiRoutes.use( function( req, res, next ){
//. ポスト本体、URLパラメータ、HTTPヘッダいずれかにトークンがセットされているか調べる var token = req.body.token || req.query.token || req.headers['x-access-token']; if( !token ){
//. トークンが設定されていなかった場合は無条件に 403 エラー return res.status(403).send( { success: false, message: 'No token provided.' } ); } //. 設定されていたトークンの値の正当性を確認 jwt.verify( token, app.get( 'superSecret' ), function( err, decoded ){ if( err ){ //. 正当な値ではなかった場合はエラーメッセージを返す return res.json( { success: false, message: 'Invalid token.' } ); } //. 正当な値が設定されていた場合は処理を続ける req.decoded = decoded; next(); }); }); //. 以下はトークンがないと使えない API //. GET(http://localhost:8080/api/) apiRoutes.get( '/', function( req, res ){ res.json( { message: 'Welcome to API routing.' } ); }); //. GET(http://localhost:8080/api/users) apiRoutes.get( '/users', function( req, res ){ res.json( users ); }); //. /api 以下に API をルーティング app.use( '/api', apiRoutes ); app.listen( port ); console.log( 'server started http://localhost:' + port + '/' );

肝になるのはルーティングに認証フィルタを定義している箇所です。ここよりも前(上)で定義した内容には認証フィルタは有効にならないので、認証なしで使える API となります(つまり GET / と POST /authenticate は認証していなくても使えます)。

この POST /authenticate API でポストデータ user, password を受取り、その値が変数 users の中で定義されているいずれかの組み合わせと一致していれば 24H 有効なトークンが発行されます(これを以下の API 実行時にパラメータ指定します)。

一方、ここよりも後(下)で定義する内容には認証フィルタが有効になり、GET /api と GET /api/users は上記方法で取得したトークンがパラメータに設定されていないと正しく処理されない API となります。


実際にこのアプリケーションを実行し($ node app)、curl コマンドで挙動を確認してみましょう。まずは問題なく実行できるはずの GET / を実行します:
$ curl -XGET 'http://localhost:8080/'
Hello. The API is at http://localhost:8080/api

問題なく実行できました。次は認証フィルタをかけた GET /api を実行してみます:
$ curl -XGET 'http://localhost:8080/api'
{"success":false,"message":"No token provided."}

API を実行した結果、「トークンがない」時のエラーメッセージが表示されました。ここも期待通りに動いています(試しませんが、ユーザー一覧を取得する GET /api/users も同様のエラーになります)。

では POST /authenticate で認証してトークンを取得してみますが最初はわざとパスワードを間違えてみます:
$ curl -XPOST -H 'Content-Type:application/json' 'http://localhost:8080/authenticate' -d '{"name":"user1","password":"pass0"}'
{"success":false,"message":"Authentication failed."}

先程同様にエラーになりましたが、エラーメッセージが「認証失敗」に変わりました。では改めて正しいパスワードを指定して実行してみます:
$ curl -XPOST -H 'Content-Type:application/json' 'http://localhost:8080/authenticate' -d '{"name":"user1","password":"pass1"}'
{"success":true,"message":"Authentication successfully finished.","token":"XXXXXX...XXXXXX"}

今度は認証が成功しました。レスポンスにも "token" が含まれています。最後にここで返ってきた token の値を指定して、先程アクセスできなかった GET /api を実行してみます:
$ curl -XGET 'http://localhost:8080/api?token=XXXXXX...XXXXXX'
{"message":"Welcome to API routing."}

今度は API が実行できました。同様にして GET /api/users も実行できるはずです:
$ curl -XGET 'http://localhost:8080/api/users?token=XXXXXX...XXXXXX'
[{"name":"user0","password":"pass0","admin":true},{"name":"user1","password":"pass1","admin":false},{"name":"user2","password":"pass2","admin":false},{"name":"user3","password":"pass3","admin":false}]


こんな感じで API の実行可否をトークンで制御できるようになりました。

今回の例ではソースコード内に静的に用意されたユーザー一覧を使って認証を行いましたが、実際の運用ではデータベース内に定義されたテーブル情報などを使うことになると思います。ただ JWT の基本的な考え方はこの1つのソースファイルだけで実現できているので、応用しやすいと思っています。

 

以前のブログエントリの中で Hyperledger Composer を使うことでブロックチェーンのビジネスネットワークを比較的簡単な定義で動かすことができることを紹介しました:
Hyperledger Composer フレームワークを使ってみる

↑ここで紹介したように Hyperledger Fabric v1.0 と Hyperledger Composer を使うことで、"asset" と呼ばれる取扱データ、"participant" と呼ばれるユーザー、 "transaction" と呼ばれる実行処理、そして "ACL" と呼ばれるアクセス権管理を定義してブロックチェーン環境に簡単にデプロイすることができるようになります。

この方法でデプロイしたブロックチェーンネットワークを外部のプログラムから使う方法も何通りかあるのですが、今回はその中から「Composer の内容を Web API 化」して、外部からは HTTP(S) を使った REST API として使えるように公開する方法を紹介します。以下の手順を実際に試す場合はローカル環境内に Hyperledger Fabric v1.0 および Hyperledger Composer がインストールされている必要があります。その手順は以下を参照して、ローカル環境で Hyperledger Composer が使える状態を作っておいてください:
Hyperledger Composer フレームワークをインストールする


また、実際に REST API として公開する内容のビジネスネットワークを定義した .bna ファイルが必要です。今回は以下のページで紹介されている方法に従って my-network.bna ファイルを作り、それを使うことにします(以下に日本語で解説します):
Developer Tutorial for creating a Hyperledger Composer solution


ではビジネスネットワークの定義ファイルを用意するまでの手順を紹介します。今回は github.com に公開されているサンプルをベースにクローンして用意します。

まず、上記リンク先の手順に従って Hyperledger Fabric v1.0 および Hyperledger Composer が導入された環境を用意して、両方のサービスを有効にします。

次に同環境にログインし、作業ディレクトリ(以下の例では ~/work)を作って、サンプルプロジェクトを git clone します:
$ mkdir ~/work (作業ディレクトリ)
$ cd ~/work
$ git clone https://github.com/hyperledger/composer-sample-networks.git

このサンプルプロジェクト内の basic-sample-network の内容を my-network という名前でコピーします:
$ cp -r ./composer-sample-networks/packages/basic-sample-network/  ./my-network

my-network プロジェクトの package.json ファイルを変更します。変更内容は name と prepublish 内のプロジェクト名を "my-network" にすることと、description の内容を変えることです:
    :
  "name": "my-network",
  "version": "0.1.6",
  "description": "My Commodity Trading network",
  "networkImage": "https://hyperledger.github.io/composer-sample-networks/packages/basic-sample-network/networkimage.svg",
  "networkImageanimated": "https://hyperledger.github.io/composer-sample-networks/packages/basic-sample-network/networkimageanimated.svg",
  "scripts": {
    "prepublish": "mkdirp ./dist && composer archive create --sourceType dir --sourceName . -a ./dist/my-network.bna",
    "pretest": "npm run lint",
    :

そして実際のビジネスネットワークの内容を書き換えます。定義する内容は上記ブログエントリの中で紹介したものと同じ定義をこのプロジェクト内にも作成することにします。というわけでまずは models/sample.cto ファイルを開き、以下の内容に書き換えて保存します:
/**
 * My commodity trading network
 */
namespace org.acme.mynetwork
asset Commodity identified by tradingSymbol {
    o String tradingSymbol
    o String description
    o String mainExchange
    o Double quantity
    --> Trader owner
}
participant Trader identified by tradeId {
    o String tradeId
    o String firstName
    o String lastName
}
transaction Trade {
    --> Commodity commodity
    --> Trader newOwner
}

↑ Commodity という asset と、Trader という participant と、Trade という transaction を定義しています。

同様にして lib/sample.js ファイルを開き、以下の内容に書き換えます:
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Track the trade of a commodity from one trader to another
 * @param {org.acme.mynetwork.Trade} trade - the trade to be processed
 * @transaction
 */
function tradeCommodity(trade) {
    trade.commodity.owner = trade.newOwner;
    return getAssetRegistry('org.acme.mynetwork.Commodity')
        .then(function (assetRegistry) {
            return assetRegistry.update(trade.commodity);
        });
}

↑tradeCommodity という処理を定義しています。

そして同様にして permissions.acl ファイルも以下の内容に書き換えます:
/**
 * Access control rules for mynetwork
 */
rule Default {
    description: "Allow all participants access to all resources"
    participant: "ANY"
    operation: ALL
    resource: "org.acme.mynetwork.*"
    action: ALLOW
}

rule SystemACL {
  description:  "System ACL to permit all access"
  participant: "org.hyperledger.composer.system.Participant"
  operation: ALL
  resource: "org.hyperledger.composer.system.**"
  action: ALLOW
}

↑デフォルトで全参加者にリソースへのアクセス権を与えるという内容です。


ではここまでに定義した models/sample.cto, lib/sample.js, permissions.acl の内容でビジネスネットワークをビルドします:
$ cd ~/work/my-network
$ npm install

このコマンドが成功すると、 my-network/dist フォルダ内に my-network.bna ファイルが生成されます。このファイルと Hyperledger Composer を使って Hyperledger Fabric v1.0 に同ビジネスネットワークをデプロイします:
$ cd dist
$ composer network deploy -a my-network.bna -p hlfv1 -i PeerAdmin -s randomString

デプロイが成功しているかどうかは以下の ping コマンドで確認できます:
$ composer network ping -n my-network -p hlfv1 -i admin -s adminpw

ここまでの作業でビジネスネットワークを定義し、Hyperledger Fabric v1.0 上にデプロイすることができました。最後にこのビジネスネットワークを Web API 化して HTTP クライアントから REST でアクセスできるようにします。 そのためには composer-rest-server というツールを使います。composer-rest-server は npm を使ってインストールします:
$ sudo npm install -g composer-rest-server

composer-rest-server の使い方は REST API 化したい Hyperledger Composer プロジェクト上でコマンド実行するだけです:
$ cd ~/work/my-network
$ composer-rest-server

すると Hyperledger-Composer ロゴが現れ、知る人ぞ知る Strongloop loopback のようなインターフェースでのプロパティ指定画面になります:
2017081401


質問内容に以下のように答えます:
 Fabric Connection Profile Name: hlfv1
 Business Network Identifier: my-network
 Fabric username: admin
 secret: adminpw
 namespaces: never use namespaces
 (ここから下はデフォルトのまま)
 REST API to be secured: No
 event publication over WebSockets: Yes
 TLS security: No
2017081402


すると上記画面のように http://(IPアドレス):3000/explorer と表示されます。ウェブブラウザでこの URL にアクセスすると、(これも知る人ぞ知る StrongLoop Loopback のような)定義したビジネスネットワークに REST API でアクセスするための Open API ドキュメントが表示されます:
2017081403


この画面からは定義した Commodity や Trader, Trade といった asset, perticipant, transaction を読み書き実行するための各 API を展開したり、
2017081404


実際にパラメータを指定して実行したりすることもできます:
2017081405


この方法であればブロックチェーンにあまり詳しくないデベロッパーでも REST API で利用できるので非常に便利といえます。

 

オープンソースのブロックチェーン環境である Hyperledger Fabric 用のフレームワークとして Hyperledger Composer が提供されています:
https://hyperledger.github.io/composer/

この Composer (と Hyperledger Fabric)を使うことでブロックチェーンアプリケーションおよびビジネスネットワークを比較的簡単に作れるようになる、というものです。

この Composer を実際に動かして体験できるサービス(Hyperledger Composer Playground)がオンライン上で公開されているので使ってみました。以下はオンライン版の Composer Playground でも、ローカル版の Composer でも同じように実行できます。なお、Composer をローカル環境に導入する場合の手順は以下を参考にしてください:
Hyperledger Composer フレームワークをインストールする


では実際に Composer を使ってみましょう。まずは Hyperledger Composer Playground にアクセスします。オンライン版であれば、http://composer-playground.mybluemix.net/editor に、ローカル環境にインストールした場合であれば composer.sh を実行後に http://localhost:8080/ にアクセスします:
2017080401


このサービスを以前に使ったことがある場合はローカルストレージに以前の情報が記憶されて残っています。初めから体験し直したい場合は、ブラウザのコンソールで
> localStorage.clear()
と実行してから以下を続けてください。


Composer Playground 起動画面の "Let's Blockchain!" と書かれたボタンをクリックしてダイアログを消すと、このような初期画面になります:
2017080402


Composer では Model, Script, ACL の3つを定義してブロックチェーン上のアプリケーション(というか挙動)を定義します。この Composer Playground はサンプルをベースにこれらを改良して、実際にデプロイして動かすことができるオンラインサービスです。

では実際にサンプルを改良してシンプルなトレードアプリを作ってみましょう。まずは Model を変更してみます。画面左で "Model File models/sample.cto" と書かれた箇所をクリックして選択します。するとこのファイルの内容が画面右のエディタで表示されます:
2017080403


画面右はエディタになっているので編集可能です。デフォルトの中身を全て消し、代わりに以下の内容を(コピペなどで)入力します:
/**
 * My commodity trading network
 */
namespace org.acme.mynetwork
asset Commodity identified by tradingSymbol {
    o String tradingSymbol
    o String description
    o String mainExchange
    o Double quantity
    --> Trader owner
}
participant Trader identified by tradeId {
    o String tradeId
    o String firstName
    o String lastName
}
transaction Trade {
    --> Commodity commodity
    --> Trader newOwner
}

※入力直後に画面が以下のようになり、他のファイルでエラーが発生します。これは Model が変更になって、その Model に合わない内容が Script や ACL に設定されているためのエラーです。このエラーはこの後で修正していきます:
2017080404


※またエディタ内で編集した内容は自動的に保存されるようになっていますが、うまく働かないこともあるようです。その場合は Ctrl+S を実行して強制保存してください。環境によっては画面に HTML の保存ダイアログが出てしまうこともありますが、そちらはキャンセルしてください。


namespace (org.acme.mynetwork) を定義した上で、"Commodity" という asset 1つ(id は tradingSymbol)、"Trader" という participant 1つ(id は tradeId)、そして "Trade" という transaction 1つを定義しています。Model ではこのように取り扱うオブジェクトを asset 、取り扱う人(ネットワーク参加者)を participant、実行する処理を transaction と呼び、これらをまとめて定義するのが Model です。

では次にこの Model に合うように Script を変更します。画面左の "Script File lib/sample.js" と書かれた部分をクリックし、画面右のエディタで以下の内容に書き換えます:
2017080405
/**
 * Track the trade of a commodity from one trader to another
 * @param {org.acme.mynetwork.Trade} trade - the trade to be processed
 * @transaction
 */
function tradeCommodity(trade) {
    trade.commodity.owner = trade.newOwner;
    return getAssetRegistry('org.acme.mynetwork.Commodity')
        .then(function (assetRegistry) {
            return assetRegistry.update(trade.commodity);
        });
}

このスクリプトでは tradeCommodity という関数1つだけが定義されており、パラメータ内変数の書き換えを行った後でレジストリを取り出し、内容を書き換える、という処理を行っています。

最後に ACL を変更します。同様にして画面左の "Access Control permissions.acl" と書かれた箇所をクリックし、画面右のエディタで以下の内容に編集します:
2017080406
/**
 * Access control rules for mynetwork
 */
rule Default {
    description: "Allow all participants access to all resources"
    participant: "ANY"
    operation: ALL
    resource: "org.acme.mynetwork.*"
    action: ALLOW
}

rule SystemACL {
  description:  "System ACL to permit all access"
  participant: "org.hyperledger.composer.system.Participant"
  operation: ALL
  resource: "org.hyperledger.composer.system.**"
  action: ALLOW
}

↑デフォルトで全参加者にリソースへのアクセス権を与えるというシンプルな内容です。

ではここまでの変更内容を実際のブロックチェーンに反映させてみます。画面左下の "Deploy" ボタンをクリックします:
2017080401


画面右上に "Deploy Successful" と表示されればデプロイは成功です。これだけで定義した内容が Blockchain に反映されました、簡単ですね:
2017080403


Hyperledger Composer ではブロックチェーン上での動作確認を行うことも可能です。デプロイ後に "test" と書かれたタブを選択します。まずは Perticipant を登録してみましょう。画面左で "Trader" と書かれた箇所をクリック(※)し、画面右上の "+ Create New Participant" と書かれたボタンをクリックします:
2017080402


※画面内に "Trader" という表示が出てこなくて、"SampleParticipant" という表示しか出てこない場合は変更が画面に反映されていない状態であることを意味しています。その場合は強制的に更新するため、一度 "Define" タブに戻って、定義内容を "Export" し、エクスポートした .bna ファイルを "Import" し直してください。これで強制的に更新を行うので "Trader" が表示されるようになるはずです:
2017080401



テキスト入力のダイアログが開くので、以下の内容を入力して "Create New" ボタンをクリックします:
2017080403
{
  "$class": "org.acme.mynetwork.Trader",
  "tradeId": "TRADER1",
  "firstName": "Jenny",
  "lastName": "Jones"
}

入力した Trader が登録されます:
2017080404


同じ作業を繰り返して、以下の Trader も登録し、2つの Trader が Participant として登録されている状態にします:
{
  "$class": "org.acme.mynetwork.Trader",
  "tradeId": "TRADER2",
  "firstName": "Amy",
  "lastName": "Williams"
}

2017080405


同様にして asset である Commodity を作成します。"Commodity" が選択された状態で "+ Create New Asset" ボタンをクリックします:
2017080401


以下の内容を入力して "Create New" ボタンをクリックし、TRADER1(Jenny)の asset "ABC" を登録します:
2017080402
{
  "$class": "org.acme.mynetwork.Commodity",
  "tradingSymbol": "ABC",
  "description": "Test commodity",
  "mainExchange": "Euronext",
  "quantity": 72.297,
  "owner": "resource:org.acme.mynetwork.Trader#TRADER1"
}

この状態で "Submit Transaction" ボタンをクリックして、トランザクションを1つ実行してみましょう:
2017080403


トランザクションの内容は先程登録した TRADER1(Jenny) の Commodity アセット(ABC)の持ち主を TRADER2(Amy) に変更する、というものとします("Submit" をクリックするとトランザクションが実行されます):
2017080404
{
  "$class": "org.acme.mynetwork.Trade",
  "commodity": "resource:org.acme.mynetwork.Commodity#ABC",
  "newOwner": "resource:org.acme.mynetwork.Trader#TRADER2"
}

トランザクション実行後、"All Transactions" にはブロックチェーン上で実行されたトランザクションが記録されます:
2017080405


また、Assets 一覧を見ると、先程 TRADER1 の所有物として登録された Commodity "ABC" の持ち主が TRADER2 に変更されたことが確認できます:
2017080406


このように Composer を使うと、ブロックチェーン上で定義すべき参加者の種類、アセットの種類、アクセス権が簡単に定義できるだけでなく、試験的にデプロイしてトランザクションを発生させた上で動作を確認することが(REST API を呼んだり、プログラミングしたりしなくても)簡単に行えるようになります。


なお、上記で紹介している内容は以下のページを参考に日本語訳と解説を加えたものです。詳しくはこちらも参照ください:
https://hyperledger.github.io/composer/tutorials/playground-guide.html
 

久しぶりの LotusScript ネタです。LotusScript は IBM ノーツ/ドミノのカスタマイズに使えるマクロ言語です。内容そのものはノーツじゃなくても(VBA でエクセルなどにも)応用できると思いますが、Windows 前提です。

Windows OS に標準搭載されている ServerXMLHTTP オブジェクトをノーツの LotusScript から使って、LotusScript で WEB API っぽいことを実現してみました。

まず ServerXMLHTTP オブジェクトについて。MSDN によるとこんなものです:
https://msdn.microsoft.com/ja-jp/library/ms762278(v=vs.85).aspx

簡単に言えば「HTTP クライアントライブラリとして使える ActiveX オブジェクト」です。このオブジェクトをインスタンス化すれば、比較的簡単に HTTP クライアントプログラムが作れます。特にノーツのマクロ言語である LotusScript はソケット通信とかネットワークプログラミングに若干弱いところがあるので、このオブジェクトを外部利用して WEB API を使ってみよう、という試みです。

例えばこんな感じ。開発環境であるドミノデザイナーを使ってノーツデータベースのエージェントを LotusScript で作り、Initialize サブルーチンに以下のような内容を記載します(エージェント名は ServerXMLHTTP としました):
Sub Initialize
  Dim obj As Variant

  Set obj = CreateObject( "Msxml2.ServerXMLHTTP.6.0" )
  Call obj.open( "GET", "http://ibm.com/", False )
  Call obj.send()
  MsgBox obj.responseText
End Sub

内容がシンプルなのでなんとなく理解できると思いますが、簡単に解説すると CreateObject を使って ServerXMLHTTP オブジェクトインタンスを生成し、"http://ibm.com/" を HTTP GET して、その内容をメッセージボックスで表示する、というものです。要するに http://ibm.com/ の HTML ソースコードを画面に表示する、というものです。

またエージェントのプロパティとして、実行時のトリガーは「イベント」で「アクションメニューの選択」、対象は「データベースの全ての文書」に設定しておきます。もちろん実行内容によってはここを変更する必要がでてきますが、今回の例ではこの設定でメニューから選択して実行できるようにしました:
2017081001


改めてこのデータベースをノーツで開くと、メニューから作成したエージェント(図では "ServerXMLHTTP")が選択できるようになっているはずです。これを選択して実行すると・・・
2017081002


こんな感じのダイアログボックスが表示され、中に http://ibm.com/ の HTML ソースコードが表示されているはずです:
2017081003


いかがでしょう。上記例では HTTP GET の例を紹介しましたが、この ServerXMLHTTP オブジェクトを使うと、POST など他のメソッドを指定することもできるし、もちろん送信データを指定することもできます。その辺りの詳しい話は公式ドキュメントを参照ください:
https://msdn.microsoft.com/ja-jp/library/ms762278(v=vs.85).aspx


HTTP クライアントがここまで簡単に使えると、各種 Web API が使えるようになるので、IBM Bluemix のワトソン API をノーツクライアントから(それもフロントエンドから)直接実行する、なんてことも可能になると思っています(余談ですが以前に Java を使って、ノーツのバックエンドからワトソン API を使う、という内容を紹介したことがあります。その記事はこちら)。


ノーツデータを広く応用・活用する際に使えそうなライブラリです。

先日の Maker Fair Tokyo 2017 でラズパイ用の小型 TFT モニタを購入しました:


Raspberry Pi2 / Pi3用タッチスクリーンTFTモニタセット(3.5インチ)



ラズパイ用のモニタにはメーカーやサイズで色々な種類がありますが、僕が購入したのは Physical Computing Lab という会社から提供されている、3.5 インチモニタ(上図)でした。


ラズパイの用途にもよるとは思うのですが、自分の場合はある程度のセットアップをした後は「リモートからアクセスして開発環境として使う」ことが多いです。それができる環境が1万円弱で揃うってすごい時代になったものです。

なお、今までにラズパイで色々やってきた記録はこちらを参照ください:
http://dotnsf.blog.jp/tag/raspberrypi


さてラズパイに直付けモニタは必要か?というと、上でも触れましたが「ある程度のセットアップが済んでいれば」必要ないと思っています。ラズパイが起動して、ネットワークに繋がっていて、IP アドレスが分かっていればリモートから SSH や VNC などでログインして使えばいいわけです。

問題になるのは「ある程度のセットアップを済ます前」です。例えばラズパイが起動して、ネットワークに接続されていても、その IP アドレスがわからないと外部からは接続できません。(MAC アドレス等を使って)外部から IP アドレスを調べる方法がないわけではないのですが、手っ取り早いのは HDMI ケーブルとキーボード&マウスを繋げて、画面で確認する方法です。つまり「モニターが必要なくなる段階になるまでにはキーボードだけでなく、HDMI モニタとケーブルが必要」なのです。キーボードはともかく、モニターを持ち歩くのは厳しい。このジレンマをなんとかしたくて、ラズパイ一体型の小型モニタを購入してみました。

やりたいことは上記のようにセットアップの最終段階、つまり「起動後の IP アドレスの確認」です。この目的のためであれば Window システムを使った GUI である必要はなく(むしろ画面が小さくて使いにくいので GUI でないほうがよく)、CUI(キャラクター端末インターフェース)で起動できれば充分です。というわけで、あまり事例のないキャラクター端末としての小型モニタ利用の手順を、(あらかじめ用意された OS イメージではなく)自分の利用中の Raspbian 環境で使う前提でまとめました。


まず普通にラズパイをセットアップします。使っているイメージは Raspbian Jessie の最新版で、マイクロ SD カードも自分で用意したもので構いません。この時点で HDMI を使っていてもいなくても構いません(IP アドレスが固定なら SSH でも構いません)。また TFT モニタはこの時点でラズパイに取り付けておきます(まだ何も写りません)。

まずラズパイでも他のシステムでも構いませんが、以下のページにアクセスして画面下のほうにある「ドライバー一式」という所で、最新版ドライバーのファイル名を確認してください。2017/Aug/08 時点では LCD-show-160811.tar.gz が最新でした:
http://store.techshare.jp/html/page147.html

2017080801


このファイルをモニタをセットアップしたいラズパイにダウンロードします。あらためてラズパイにログインし、以下のコマンドを実行してドライバーをダウンロードします(ファイル名は上記で確認した最新版ファイルの名前を指定してください、GUI であればブラウザから直接ダウンロードも可能です):
$ wget http://techshare.co.jp/raspiosimage/LCD-show-160811.tar.gz

ダウンロードが完了したらファイルを展開します:
$ tar xzvf LCD-show-160811.tar.gz

LCD-show というフォルダが作られ、その中にドライバファイル一式が入ります。最終的な目標は「キャラクター端末としてモニタを利用する」ことなので、まずこの時点でラズパイを CUI モードに変更します(GUI でモニタを使いたい場合はこの時点でラズパイを GUI モードに変更します)。画面モードを切り替える場合は raspi-config コマンドで変更します:
$ sudo raspi-config

最初にメニュー3番目の "Boot Options" を選択します:
2017080801


次の画面で一番上の "Desktop / CLI" を選択します:
2017080802


次の画面で変更したいモードを選択します。今回は CUI モードで、ログインプロンプトを出した状態で起動したいので、一番上の "Console" を選択します(変更した場合はここでラズパイを再起動します):
2017080803



再起動後、改めてラズパイにログインし、ダウンロードしたドライバを読み込ませた状態で HDMI モードで再起動します(LCD-hdmi コマンド実行後に自動的に再起動します):
$ cd LCD-show
$ sudo ./LCD-hdmi

何度か再起動を繰り返してここまできました。最後にラズパイを TFT モニタモードに切り替えます。改めてラズパイにログイン後、モニタのサイズに合わせて LCDxx-show コマンドを実行します(以下の例は 3.5 インチモニタ用):
$ cd LCD-show
$ sudo ./LCD35-show

このコマンドが成功すると、ラズパイに接続された TFT モニタに CUI コンソールが表示されるようになります。キーボードが接続されていればコマンドを入力してその結果を確認することも可能になりました:
2017080800


TFT モニタ(の解像度)がもう少し大きいものであれば話は違ってくると思いますが、この 3.5 インチはラズパイとほぼ同じサイズで、一体感があります。一方で、このサイズのモニタだと GUI で使うこと自体に無理があると感じています。 そうなると今回紹介したように CUI で使うのが現実的かな、と考えています。

で、CUI で使うための手順紹介をあまり見かけなかったので、自分でやって紹介してみた、というのが今回のブログエントリを書いた経緯でした。 同じように考えている皆さんの参考になれば。


このページのトップヘ