7.6.Registrationの動作確認 |
---|
2022年5月7日 |
|
今度はRegistrationを動かしてみましょう。Registationの指定の例として、以下の様に温度を読み出した時に、hostpcの3001番のボード番号でListenしているContext Providerのregistrations/temperatureに値を取りに行く指定とします。今度は四階の部屋を指定していますが、三階と四階はAttributeにtemperatureは指定していませんでした。つまり、ResistrationはEntity格納時に存在しないAttributeに対して設定することになります。余談ですが、うっかりEntityの格納時にAttributeを作ってしまうと、Registrationの指定は無視され、格納したAttributeの値が返却されます。 |
|
{ "description": "Temperature Context Provider", "dataProvided": { "entities": [ { "id": "urn:ngsi-ld:Room:001-004-001", "type": "Room" } ], "attrs": [ "temperature" ] }, "provider": { "http": { "url": "http://hostpc:3001/registrations/temperature" } } } |
|
このjsonをregistrationsというエンドポイントに対してPOSTします。 |
|
curl -iX POST -H 'Content-Type: application/json' -d @d:\postRegistration.json 'http://localhost:1026/v2/registrations' | |
登録が出来たら、次はContext Providerを作りましょう。Consumerと同じくPOSTで通知されるので、似たような内容になります。 以下が今回作ったProvicerです。温度はランダムな値を返却します。通常、Providerは色々な問い合わせに対応する必要があるためもっと複雑になりますが、このプログラムはこのチュートリアルに対応する機能しか実装していません。悪しからず。 |
|
import http.server as s from urllib.parse import urlparse #url anslysis module import json import random class MyHandler(s.BaseHTTPRequestHandler): def do_POST(self): #server_foreverからPOST時に呼ばれる # urlパラメータを取得 parsed = urlparse(self.path) #url文字列を分解してnamed tupleに変換 # urlパラメータを解析 urlpath = parsed.path #パスの文字列を取り出す urldir = urlpath.split('/') if (len(urldir) < 5 or urldir[1] != 'registrations'): # Registrationによる呼出しではない print ('Context provider error (1): invalid resource: ', urlpath) self.send_response(400) #レスポンスのステータスを"Bad request"に設定 self.send_header('Content-length', 0) #ヘッダのcontect-lengthを設定 self.end_headers() #ヘッダの後に空行を出力 self.wfile.write(''.encode()) return() if urldir[2] == 'temperature':#temperatureのregistration if (urldir[3] != 'op' or urldir[4] != 'query'): # legacyForwarding":falseではない print ('Context Provider error (2): invalid resource: ', urlpath) self.send_response(400) self.send_header('Content-length', 0) self.end_headers() self.wfile.write(''.encode()) return() content_len = self.headers.get("content-length") if content_len =='': #Headerのcontent-lengthの値を採取 print ('Context Provider error (3): missing message body') self.send_response(400) self.send_header('Content-length', 0) self.end_headers() self.wfile.write(''.encode()) return() content_len = int(content_len) req_body = self.rfile.read(content_len).decode("utf-8") json_dict = json.loads(req_body) temperature = str(random.randrange(50)) print('Providing temperature information of the room ('+json_dict['entities'][0]['id']+'): '+temperature) body = '[{"id":"' body+= json_dict['entities'][0]['id'] body+= '","type":"' body+= json_dict['entities'][0]['type'] body+= '","temperature":{"type":"Integer","value":' body+= temperature body+= '}}]' else: # 知らないRegistrationによる呼出し print ('Provider error (4): invalid resource: ', urlpath) self.send_response(400) self.send_header('Content-length', 0) self.end_headers() self.wfile.write(''.encode()) return() # 返信を組み立て self.send_response(200) #レスポンスのステータスを"正常"に設定 self.send_header('Content-type', 'application/json') #ヘッダのcontect-typeを設定 self.send_header('Content-length', len(body)) #ヘッダのcontect-lengthを設定 self.end_headers() #ヘッダの後に空行を出力 self.wfile.write(body.encode()) #クライアントに応答 def do_GET(self): #server_foreverからGET時に呼ばれる print('Provider error (5): invalid method: GET') self.send_response(400) self.send_header('Content-length', '0') self.end_headers() self.wfile.write(''.encode()) def do_PUT(self): #server_foreverからPUT時に呼ばれる print('Provider error (5): invalid method: PUT') self.send_response(400) self.send_header('Content-length', '0') self.end_headers() self.wfile.write(''.encode()) print('PUT request detected') port = 3001 httpd = s.HTTPServer(("", port), MyHandler) print('Context Providerを起動しました。ポート:%s' % port) httpd.serve_forever() } |
|
筆者はこれをprovider.pyというファイルにメモ帳で格納しました。そのファイルをダブルクリックすると、起動されます。起動直後は以下のメッセージが表示されます。 |
|
Context Providerを起動しました。ポート:3001 | |
起動出来たら、早速温度を読み出してみましょう。 | |
curl -X GET 'http://localhost:1026/v2/entities/urn:ngsi-ld:Room:001-004-001?options=keyValues' | |
PS C:\Users\owner> curl -X GET 'http://localhost:1026/v2/entities/urn:ngsi-ld:Room:001-004-001?options=keyValues' {"id":"urn:ngsi-ld:Room:001-004-001","type":"Room","name":{"type":"Text","value":"レクリエーションルーム"},"refFloor":{"type":"Text","value":"urn:ngsi-ld:Floor:001-004"},"temperature":36} PS C:\Users\owner> |
|
その際に、Providerのプログラムは次の様なメッセージが表示されます。 | |
Providing temperature information of the room (urn:ngsi-ld:Room:001-004-001): 36 172.22.32.1 - - [07/May/2022 15:39:03] "POST /registrations/temperature/op/query HTTP/1.1" 200 - |
|
この様にFiware/Orionから温度を読み出そうとすると、Fiware/OrionはContext Providerに温度情報を取りに行き、Context Providerから返却された温度の値を要求者に返却していることが分かります。 | |