こんにちは。ソリューションアーキテクトの菅です。
Alibaba Cloudは、2010年のサービス開始から、地球上のデータセンターにサーバ拠点を着々と増やしています。2019年7月時点では、19の地域(リージョン)に、56の拠点(アベイラビリティーゾーン)を運営しています。
本ブログでは、DataVの利用方法を紹介するために、例として、Alibaba Cloudのリージョンを3Dの地球上にマッピングし、さらに、自身のアカウントで各リージョンに配置した、サーバ(インスタンス)を可視化する方法を紹介いたします。
完成後の画面はこのようなものになります。
右側は、リージョンの一覧と、選択したリージョンで稼働するインスタンスの一覧を表示しています。
利用するプロダクト
説明の前に、本ブログでは以下のプロダクトを利用します。個々のサービス仕様等の説明は割愛させていただきますのでご了承ください。
Alibaba Cloud
・DataV エンタープライズエディションを利用します。
・ Function Compute リージョンやインスタンスリストを取得するためのAPIサーバとして利用します。
・Elastic Compute Service インスタンスリストを表示するために利用します。(起動していなくても良いです)
位置情報サービス
・IP Geoloaction API IPアドレスやドメインから位置情報を取得できるサービスです。(無償の範囲内で利用する想定です)
1:プロジェクト作成
では、ここから作成手順を説明します。はじめにDataVのプロジェクトを作成します。
1)Alibaba Cloud コンソールにログインし、プロダクト一覧からDataVを選択します。
2)DataVコンソール画面内にあるプロジェクト作成を選択します。
3)テンプレート一覧の先頭にあるBlank Canvasを選択します。 プロジェクト名(任意の文字列)を入力します。
4)ここまで完了すると以下のような画面が表示されます。(赤字は各パーツの説明です。実際には表示されません。)
以降は、この画面を中心に作業を行います。
2:画面の初期設定
次に作成するダッシュボード画面のサイズと背景の設定をします。画面右側のページ設定にて以下を入力します。
- ページサイズ:幅1440 高さ900
- 背景色:#000000
- 背景画像:削除(カーソルを合わせるとゴミ箱が表示されます)
3:タイトルヘッダーを作成
次に画面タイトルを表示するヘッダーを作成します。
1)プロジェクト画面上部(ウィジェット選択)からカスタム背景ブロックを選択します。
2)画面右側のウィジェット設定にて以下を入力します。(その他の項目はデフォルトのままで良いです)
- サイズ:幅1440 高さ65
- 位置:横0 縦0
- 背景色:RGBA(255,255,255,0.09)
3)ウィジェット選択からタイトルを選択し、ウィジェット設定を以下のようにします。
- サイズ:幅480 高さ55
- 位置:横25 縦5
- テキストスタイル:サイズ32 #FFFFFF bolder
4)タイトルウィジェットの文字を変更するために、ウィジェット設定内にあるデータ設定タブを開き、valueの値を”Alibaba Cloud Regions”にします。
5)プロジェクト画面上部(ウィジェット選択)から全画面切り替えを選択し、ウィジェット設定を以下のようにします。
- サイズ:幅55 高さ55
- 位置:横1365 縦5
- 背景色:#000000
ここまで完了すると以下のようになります。
4:3Dマップを作成
ここから3Dマップ部分の作成を説明します。
1)ウィジェット選択から3Dの地球を選択します。 画面右側のウィジェット設定にて以下を入力します。(他はデフォルトのまま)
- サイズ:幅845 高さ832
- 位置:横0 縦65
- 背景色:RGBA(0,0,0,0)
- 視点の設定:視角90 緯度20 経度110 距離320
- 回転速度:0.5
2)3Dマップにレイヤー(視覚効果など)を追加します。ウィジェット設定にある+Component Managementを選択すると、レイヤーコンポーネントの一覧が表示されるので、以下を追加します。
- 球体レイヤー(デフォルト)
- アンビエントライトレイヤー(デフォルト)
- 大気レイヤー
- 散布レイヤー
- フロートボードレイヤー
- スキャンラインレイヤー
3)ウィジェット設定にて、各レイヤーを選択し、設定を変更します。
・球体レイヤー
マッピングタイプ:パーティクル
・アンビエントライトレイヤー
証明強度:2
・大気レイヤー
透明度:1 強さ:1.25 スケーリング:1.7
・散布レイヤー
呼吸速度:0.5 透明度:1 データ分類:7 散布サイズ:50 色:#FAAD14
・フロートボードレイヤー
高さ:5 スケーリング:40 透明度:1
・スキャンラインレイヤー
色:#91D5FF
5:位置情報をマッピングする
3Dマップウィジェットに追加した散布レイヤーにデータを入力することで、リージョンの位置に黄色い円が表示(マッピング)されます。
データ入力方法は、データベースからの取得や、JSON形式のテキストなどが選べますが、ここではCSVを利用します。
1)DataVコンソール画面TOPに戻り、データソースを選択します。
2)ソースを追加を選択し、以下の設定を行います。
- タイプ:CSVファイル
- データソース名:alibaba_regions(任意の名前で良いです)
- ファイル:本ブログ用に作成したCSVファイルをアップロードください。
3)作成画面に戻り、3Dマップのウィジェット設定にあるデータタブから散布レイヤーを選択します。
- データソースタイプ:CSVファイル
- 保存されたデータソース:alibaba_regions(または任意で設定したデータソース名)
6:リージョン名をマッピングする
次に3Dマップウィジェットのフロートボードレイヤーにデータを入力します。これを行うことで、リージョン名が表示されます。ここでは、JSONテキスト形式で行います。
2)3Dマップのウィジェット設定にあるデータタブからフロートボードレイヤーを選択し、以下の設定を行います。
- データソースタイプ:静的データ
- 本ブログ用に作成したJSON形式のデータから、テキストをデータ枠内にコピーペーストしてください。
ここまで完了すると以下のように3Dマップが完成します。
7:リージョン一覧を作成
ここからはリージョン情報の一覧を表示するための手順です。
1)ウィジェット選択からカルーセルリストを選択し、以下の設定を行います。
- サイズ:幅600 高さ290
- 位置:横805 縦:80
- テーブルのレコード数:10
- ヘッダのレコードの高さ:10%
- ヘッダ背景色:#000000
- ヘッダテキスト:色#5499FD サイズ18 太さbold
- 奇数レコード背景色:RGBA(255,255,255,0.03)
- 偶数レコード背景色:RGBA(0,0,0,0)
- コールバックフィールド:RegionId
- カスタムカラムラベル1:フィールド名LocalName 表示名Region Name 幅比50% テキストサイズ16
- カスタムからむラベル2:フィールド名RegionId 表示名Region ID 幅比50% テキストサイズ16
8:リージョン一覧APIを作成
ここでFunction Computeを利用してAPIの作成を行います。これを行うことでリージョン一覧を取得するAPIができ、DataVのデータソースに指定することができます。
1)Function Computeのコンソール画面からサービス作成を行います。(サービス名は任意で良いです)
2)関数の作成を行います
- 関数テンプレート:空の関数
- 関数名:getAlibabaCloudRegions(任意名)
- トリガータイプ:HTTPトリガー
- トリガー名:HttpTrigger(任意名)
- 承認:anonymous
- メソッド:GET
- ランタイム:Python3
- オンライン編集:ここにソースコードを入力します。
# -*- coding: utf-8 -*- import logging import urllib.request import json import sys from aliyunsdkcore.client import AcsClient from aliyunsdkcore.acs_exception.exceptions import ClientException from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkecs.request.v20140526.DescribeRegionsRequest import DescribeRegionsRequest ACCESSKEY_ID = "" ACCESSKEY_SEC = "" # if you open the initializer feature, please implement the initializer function, as below: # def initializer(context): # logger = logging.getLogger() # logger.info('initializing') # ここでAlibaba APIをコールしてリージョン一覧を取得しています def describeRegionRequest(): global ACCESSKEY_ID, ACCESSKEY_SEC client = AcsClient(ACCESSKEY_ID, ACCESSKEY_SEC) request = DescribeRegionsRequest() request.set_accept_format('json') response = client.do_action_with_exception(request) return str(response, encoding='utf-8') # ip-apiをコールして緯度経度を取得しています def getRegionGEO( region_end_point ): url = 'http://ip-api.com/json/' + region_end_point req = urllib.request.Request(url) with urllib.request.urlopen(req) as res: body = json.loads( res.read() ) if body['lat'] and body['lon']: return ( body['lat'], body['lon'] ) def mergeRegionGEO( org_json ): org_dict = json.loads(org_json) rtn_dict = [] for r in org_dict['Regions']['Region']: geo = getRegionGEO( r['RegionEndpoint'] ) if len(geo) == 2: r['lat'] = geo[0] r['lng'] = geo[1] rtn_dict.append(r) if len(rtn_dict) > 0: return json.dumps(rtn_dict, ensure_ascii=False) else: raise ClientException("200 OK", "No data") # HTTPトリガーからコールされる関数です。ここからスタートします。 def handler(environ, start_response): try: global ACCESSKEY_ID, ACCESSKEY_SEC ACCESSKEY_ID = environ['accessKey'] ACCESSKEY_SEC = environ['secretKey'] response_body = mergeRegionGEO( describeRegionRequest() ) status = '200 OK' response_headers = [('Content-type', 'text/json')] start_response(status, response_headers) return [bytes(response_body, 'utf-8')] except Exception as e: #print(sys.exc_info()) status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [bytes(e.message, 'utf-8')]
3)関数作成後に環境変数を設定します。 自身のAlibaba CloudアカウントのAccessKey IDとAccess Key Secretを、上記で作成した関数の環境変数として登録します。(変数名はaccessKey、secretKeyとしてください)
4)カルーセルリストのデータソースとしてAPIを設定します。 DataVの画面に戻り、上記で作成したカルーセルリストのデータ設定を以下のように行います。
- データソースタイプ:API
- URL:関数トリガーに記載されているHTTP URL
5)データ応答参照をクリックすると以下のようにAPIからの取得データが表示されます。(リージョン名が中国語ですがご了承ください)
ここまで完了すると以下のような画面になります。
9:ECSインスタンス一覧を作成
1)ウィジェット選択からカルーセルリストを選択し、以下の設定を行います。
- サイズ:幅600 高さ290
- 位置:横805 縦:400
- テーブルのレコード数:10
- ヘッダのレコードの高さ:10%
- ヘッダ背景色:#000000
- ヘッダテキスト:色#5499FD サイズ18 太さbold
- 奇数レコード背景色:RGBA(255,255,255,0.03)
- 偶数レコード背景色:RGBA(0,0,0,0)
- カスタムカラムラベル1:フィールド名InstanceName 表示名InstanceName 幅比40% テキストサイズ16
- ラベル2:フィールド名InstanceType 表示名Type 幅比40% テキストサイズ16
- ラベル3:フィールド名Status 表示名Status 幅比20% テキストサイズ16
10:インスタンス一覧APIを作成
1)Function Computeコンソールにて関数の作成を行います
- 関数テンプレート:空の関数
- 関数名:getAlibabaEcsInstances(任意名)
- トリガータイプ:HTTPトリガー
- トリガー名:HttpTrigger(任意名)
- 承認:anonymous
- メソッド:GET
- ランタイム:Python3
- オンライン編集:
# logger.info('initializing') def describeInstances(region_id): global ACCESSKEY_ID, ACCESSKEY_SEC client = AcsClient(ACCESSKEY_ID, ACCESSKEY_SEC, region_id) request = DescribeInstancesRequest() request.set_accept_format('json') #print(dir(request)) request.set_PageSize(100) response = client.do_action_with_exception(request) #print(response) return str(response, encoding='utf-8') def makeJson( org_json ): org_dict = json.loads(org_json) rtn_dict = [] tmp_json = {} ix = 0 for r in org_dict['Instances']['Instance']: tmp_json['InstanceName'] = r['InstanceName'] tmp_json['InstanceType'] = r['InstanceType'] tmp_json['OSName'] = r['OSName'] tmp_json['Status'] = r['Status'] rtn_dict.append(tmp_json) tmp_json = {} if len(rtn_dict) > 0: return json.dumps(rtn_dict, ensure_ascii=False) else: raise ClientException("200 OK", "No data") def handler(environ, start_response): try: logger = logging.getLogger() global ACCESSKEY_ID, ACCESSKEY_SEC ACCESSKEY_ID = environ['accessKey'] ACCESSKEY_SEC = environ['secretKey'] # Defaultは東京リージョン region_id = "ap-northeast-1" if 'QUERY_STRING' in environ: # 注意:DataVからのリクエストは末尾に&spmが付くよ query_arr = re.split('[=&]', environ['QUERY_STRING']) if len(query_arr) >= 2 and query_arr[0] == 'region_id': region_id = query_arr[1] response_body = makeJson(describeInstances(region_id)) status = '200 OK' response_headers = [('Content-type', 'text/json')] start_response(status, response_headers) return [bytes(response_body, 'utf-8')] #else: # raise ClientException("200 OK", "undefined region_id") except Exception as e: #print(sys.exc_info()) status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [bytes(e.message, 'utf-8')]
以降の手順はリージョン一覧作成時と同じです。
11:選択したリージョン名を表示する
リージョン一覧にあるレコードをクリックすると、リージョン名を一覧の下に表示するようにします。
1)事前にDataVのコンソールTOPからデータソース設定にて、外部のデータベースサーバへの接続設定を追加する必要があります。(DBテーブルやレコードは不要です)
2)タイトルウィジェットを選択します。 データ設定にて、データタイプをデータベースにします。上記で設定したデータソース名を指定します。 以下のSQL文を入力します。
SELECT CASE WHEN :RegionId != "" THEN :RegionId ELSE "Select a Region from above list" END as value;
ここまで完了すると以下のような画面になります。
12:プレビューと外部公開
DataV画面上部の右側にプレビューボタンがあり、それをクリックすると別タブが起動し、作成したダッシュボードが表示されます。これは公開前の状態です。
公開をするにはプレビューボタンの隣にある公開ボタンをクリックし、パスワード等を設定することで外部に公開する状態になります。(公開用URLが表示されるのでそれを他者に配布します)
まとめ
以上で手順は完了です。
今回はCSVファイルと、静的JSONデータ、Function Computeを使ったAPIを通して、DataVのダッシュボードを作成する実例を掲載させていただきました。
実は、Open APIから取得した緯度経度情報は、マッピングデータとしては利用しませんでした。
Alibaba Cloud のAPIから取得したドメイン情報が、中国のリージョンの場合は同じものが返却されるため、全て同じ緯度経度となるためです。
ソースコードは残しているので参考までにご確認ください。ECSに割り当てたグローバルIPアドレスだったらうまくいくのかもしれません。
いづれにせよ、本ブログではDataVの紹介を目的としているので、設定やコード等の保証はいたしませんことをご了承ください。
以上、長々と失礼しました。