django-rest-frameworkのserializerでいろんなメソッドの呼ばれる順番
注釈
- 元記事は以下
- 筆者は同一ですが、こっちに移します
この記事の目的
環境
- djangorestframework: 3.9.1
見るところ
- rest_framework/serializers.py
class Serializer(BaseSerializer)
の辺り- とりあえずここ理解すれば他もなんとかなる?
読む
- renderersとかmixinsとかは後回しでいきなりserializers
to_internal_value(self, data)
471 def to_internal_value(self, data): 472 """ 473 Dict of native values <- Dict of primitive datatypes. 474 """ 475 if not isinstance(data, Mapping): 476 message = self.error_messages['invalid'].format( 477 datatype=type(data).__name__ 478 ) 479 raise ValidationError({ 480 api_settings.NON_FIELD_ERRORS_KEY: [message] 481 }, code='invalid')
- 受け取ったデータ型の検証とか?
483 ret = OrderedDict() 484 errors = OrderedDict() 485 fields = self._writable_fields
ret
: 最終的な返却値errors
: 例外情報fields
:to_internal_value
で処理する対象が格納されている。_writable_fields
は以下の通り。
367 @cached_property 368 def _writable_fields(self): 369 return [ 370 field for field in self.fields.values() if not field.read_only 371 ]
read_only
プロパティがFalse
になっているfieldだけが含まれるらしい。
487 for field in fields: 488 validate_method = getattr(self, 'validate_' + field.field_name, None) 489 primitive_value = field.get_value(data) 490 try: 491 validated_value = field.run_validation(primitive_value)
- fieldの
run_vaildation
を実行
523 def run_validation(self, data=empty): 524 """ 525 Validate a simple representation and return the internal value. 526 527 The provided data may be `empty` if no representation was included 528 in the input. 529 530 May raise `SkipField` if the field should not be included in the 531 validated data. 532 """ 533 (is_empty_value, data) = self.validate_empty_values(data) 534 if is_empty_value: 535 return data 536 value = self.to_internal_value(data) 537 self.run_validators(value) 538 return value
- 渡ってきた値の
to_internal_value
を呼び出し。- ここの処理はまた今度読む
492 if validate_method is not None: 493 validated_value = validate_method(validated_value)
validate_<field名>
という名前でメソッドが宣言されてたらそれを実行する
494 except ValidationError as exc: 495 errors[field.field_name] = exc.detail 496 except DjangoValidationError as exc: 497 errors[field.field_name] = get_error_detail(exc) 498 except SkipField: 499 pass
- 例外が発生したらerrorsに入れる
500 else: 501 set_value(ret, field.source_attrs, validated_value)
- validate_<field名>のメソッドを実行した結果を
ret
に入れる
503 if errors: 504 raise ValidationError(errors)
- 何かしらのエラーがあったら例外発火
506 return ret
to_representation
508 def to_representation(self, instance): 509 """ 510 Object instance -> Dict of primitive datatypes. 511 """ 512 ret = OrderedDict() 513 fields = self._readable_fields
fields
:_readable_fields
で取得_readable_fields
は以下の処理write_only
でないフィールドを取得している
373 @cached_property 374 def _readable_fields(self): 375 return [ 376 field for field in self.fields.values() 377 if not field.write_only 378 ]
514 515 for field in fields: 516 try: 517 attribute = field.get_attribute(instance) 518 except SkipField: 519 continue
instance
から指定のフィールドに格納されているデータを取得
521 # We skip `to_representation` for `None` values so that fields do 522 # not have to explicitly deal with that case. 523 # 524 # For related fields with `use_pk_only_optimization` we need to 525 # resolve the pk value. 526 check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute 527 if check_for_none is None: 528 ret[field.field_name] = None 529 else: 530 ret[field.field_name] = field.to_representation(attribute)
- コメントのとおり…
to_internal_value
と同様に、fieldのto_representation
も順に呼び出される
531 532 return ret
まとめ
- to_internal_value
- 各fieldに対して
to_internal_value
とvalidationを繰り返してる - オブジェクトがネストされているときは、深いところから
to_internal_value
とvalidate_<field名>
が実行されることになりそう
- 各fieldに対して
- to_representation
- 各
field
のto_representation
を呼び出してるくらい?
- 各
field.to_internal_value
とかfield.to_representation
はまた今度読む
Cisco 1812j でOSPFを動かすためのコンフィグ
やったこと
Cisco 1812jを用いてマルチエリアOSPFネットワークを構築。
設定を入れて、実際のパケットの流れとか追ってみた。
構成
Endpoint Device1 --- Router1(C1812j) --- Router2(C1812j) --- Endpoint Device2
Cisco 1812jはFastether0とFastether1のインターフェースを持つ。Router間の接続にFastether 0、RouterとEndpoint Deviceの接続にFastether 1を使用した。
コンフィグ
事前準備
IPアドレス設定
Router1
Router1(config)# interface fastether 0 Router1(config-if)# no shutdown Router1(config-if)# ip address 192.168.0.1 255.255.255.0 Router1(config)# interface fastether 1 Router1(config-if)# no shutdown Router1(config-if)# ip address 192.168.1.1 255.255.255.0
Router2
Router2(config)# interface fastether 0 Router2(config-if)# no shutdown Router2(config-if)# ip address 192.168.0.2 255.255.255.0 Router2(config)# interface fastether 1 Router2(config-if)# no shutdown Router2(config-if)# ip address 192.168.2.1 255.255.255.0
DHCP設定
Router1
Router1(config)# ip dhcp pool network1 Router1(dhcp-config)# network 192.168.1.0 /24 Router(dhcp-config)# default-router 192.168.1.1 Router(dhcp-config)# dns-server 192.168.1.1
Router2
Router2(config)# ip dhcp pool network2 Router2(dhcp-config)# network 192.168.2.0 /24 Router2(dhcp-config)# default-router 192.168.2.1 Router2(dhcp-config)# dns-server 192.168.2.1
本題
OSPF設定
Router1
area 0
Router1(config)# router ospf 1 Router1(config-router)# network 192.168.0.0 0.0.0.255 area 0
area 1
Router1(config)# router ospf 1 Router1(config-router)# network 192.168.1.0 0.0.0.255 area 1
Router2
area 0
Router2(config)# router ospf 1 Router2(config-router)# network 192.168.0.0 0.0.0.255 area 0
area 1
Router2(config)# router ospf 1 Router2(config-router)# network 192.168.2.0 0.0.0.255 area 2
これでコンバージェンスを待つと通信ができるようになる。
仕組みの話は今度調べてまとめる
Ubuntu 14.04でJavaScriptエンジンのSpidermonkeyをビルドして逆アセンブルする
Mozillaのfirefoxに搭載されているJavaScriptエンジンであるSpidermonkeyをビルドする.
今回は実行したJavaScriptコードを逆アセンブルできるようにする.
公式はこちら
準備
# apt-get install autoconf
ソースの取得
# git clone https://github.com/mozilla/gecko-dev.git
ビルド
# cd gecko-dev/js/src # autoconf # mkdir Debug # cd Debug # ../configure --enable-debug --disable-optimize # make
これでdis()とかdissrc()とかできる.
Ubuntu 12.04 LTS で GoogleのJavaScriptエンジンV8をスタンドアロンで動かす
基本的には公式のドキュメントに従って進めるだけ.
今回は実行するJavaScriptを逆アセンブルしたコードを出力させるようにする.
Prepare
$ sudo apt-get install gcc g++ git subversion gcc-multilib g++-multilib
Install depot_tools
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $ export PATH="$PATH":`pwd`/depot_tools
Get source code
$ svn co http://v8.googlecode.com/svn/trunk v8
Prerequisite: Installing GYP
$ cd v8 $ make dependencies
Building
$ make -j4 release disassembler=on
Run
$ cd out/xxx.release $ ./d8 hoge.js -print-code
rfc4960 key term
RFC 4960のkey termを日本語っぽくしてみた.
- active distination transpot address:
ユーザメッセージを受け取ることができるトランスポートアドレス
IPアドレスとポート番号の組
- bundling:
多重化処理.複数ののユーザメッセージを単一のSCTPパケットで配送できる.
- chunk:
SCTPパケットの情報の単位.チャンクヘッダとチャンク本体から成る.
- congestion window(cwnd):
確認応答を受け取る前に,送信者が特定のトランスポートアドレスに送信できるデータのバイト数を制限するSCTPの変数.
- cumulative tsn ack point:
SACKのCumulative TSN Ackフィールドによって通知された最後のデータチャンクのTSN.
(TSN: Transmission Sequence Number)
- idle destination address:
ある一定期間(ハートビートの間隔またはそれ以上)ユーザメッセージが送られなていないトランスポートアドレス.
- message(user message):
上位レイヤプロトコル(ULP)からSCTPに渡されるデータ
- message authentication code(MAC):
秘密鍵を用いて暗号ハッシュ関数に基づいて,整合性をチェックするメカニズム.
主にMACは秘密鍵を共有したパーティの間で,転送された情報の検証のために使われる.SCTPでは,CookieEchoチャンクでピアから返されるState Cookie情報の検証のために用いられる.
"MAC"という用語は,文脈によって異なる意味を持つ.SCTPはRFC2104と同じ意味を持つ.
- NetwokByteOrder:
ビッグエンディアン
- orderd Message:
メッセージが送信されたストリームで,以前に送信された全てのユーザメッセージに関して順番に配信されているユーザメッセージ.(←?)
- outstanding TSN(at an SCTP endpoint):
送信されたが,確認応答を受け取っていないTSN(またはそれに関連付けられたデータチャンク)
- Path:
SCTPエンドポイントの特定の宛先トランスポートアドレスへSCTPエンドポイントのよって送信されたSCTPパケットが通るルート.異なる宛先トランスポートアドレスに送信することはパスが分割されることを保証しない.
- primary path:
デフォルトでパケットが出ていく宛先と送信元アドレス.定義が送信元を含むのは,送信者がマルチホームのとき,応答チャンクが通る特定の経路や,パケットが転送されるインターフェースを制御するために,宛先と送信元のアドレスを特定したいかもしれないから.
- Receiver Window(rwnd):
データ送信者が,直近で計算した受信者ウィンドウを,バイト単位で格納するために用いる変数.
受信者が送信者に,受信バッファの空き容量を通知することができるようにする.
- SCTP Association:
SCTPエンドポイント間の,二つのSCTPエンドポイントとVerification TagsやアクティブなTSN集合などを含む,プロトコル状態情報からなる関連づけ.アソシエーションは,エンドポイントのトランスポートアドレスによって一意に特定される.二つのSCTPエンドポイントは,常に1つ以上のアソシエーションを持たなければならない.
- SCTP endpoint:
SCTPパケットの論理的な送信者と受信者.マルチホームホストにおいて,SCTPエンドポイントは,送信可能なトランスポートアドレスの集合と受信可能なトランスポートアドレスの集合の組合せとして表現されている.一つのSCTPエンドポイントによって用いられるトランスポートアドレスは,同じポート番号を用いなければならない.しかし複数のIPアドレスを使用することは可能.つまり,トランスポートアドレスはSCTPエンドポイントで一意である.
- SCTP packet(packet):
SCTPとコネクションレスパケットネットワークの間で配送されるデータ単位である.SCTPパケットは,SCTP共通ヘッダ,制御チャンク,DATAチャンクにカプセル化されたユーザデータを含む.
- SCTP user application(SCTP user):
SCTPのサービスを利用する論理的な上位レイヤアプリケーション.(ULP)
- Slow-Start Threshold(ssthresh):
SCTPの変数.特定のトランスポートアドレスにおいて,スロースタートや輻輳回避を用いるかどうかを決定するために使う.バイト単位で表現される.
- Stream:
SCTPエンドポイントから関連付けられた他方のエンドポイントに生成される,単方向の論理的な経路.順序付けなし配送サービスでメッセージ以外の全てのユーザメッセージはこれの上で順番に送信される.
- Stream Sequence Number:
SCTP内部で,ストリームでユーザメッセージの順序付けられた配送を保証するために用いる16ビットのシーケンス番号.一つのStream Sequence Numberは各ユーザメッセージに紐付けられる.
- Tie-Tags:
64ビットのnonceを作る二つの32ビット乱数.これらのタグは,新たに再開されるアソシエーションが再開せず,既存のアソシエーションの真のVerification Tagsが明らかになっていないエンドポイントの元のアソシエーションにリンクされるようにするために,StateCookieとTCBに用いられる.
- Transmission Control Block(TCB):
他のSCTPエンドポイントへの既存のSCTPアソシエーションのために,SCTPエンドポイントによって生成されるデータの内部構造.TCBはエンドポイントが対応するアソシエーションを維持管理するための全ての状態や処理情報を含む.
- Transmiission Sequence Number(TSN):
SCTPが内部で使う32ビットのシーケンス番号.一つのTSNは,受信SCTPエンドポイントに受信や重複検知の確認応答をすること可能にするためにユーザデータを含む各チャンクに紐付けられる.
- Transpot Address:
トランスポートアドレスは従来,ネットワーク層のアドレスとトランスポート層のプロトコルによって定義されていた.IP上で動作しているSCTPの場合,トランスポートアドレスは,IPアドレスとSCTPポート番号の組合せによって定義される.
- Unacknowledged TSN(at an SCTP endpoint):
エンドポイントによって受信はされたが,確認応答が送信されていないTSN,または逆に,送信はしたが確認応答が帰ってきていないパケットのTSN
- Unordered Message:
Unordered Messagesは他のメッセージに関して順不同である.これには,他の順不同メッセージだけでなく,他の順序付けられたメッセージも含む.順不同メッセージは,同一ストリームで送信された,順序付けられたメッセージの前や後に配送され得る.
- User Message:
SCTPとユーザの間のインターフェース間で配送されるデータ単位.
- Verification Tag:
ランダムに生成される32ビット符号なし整数.Verification Tagは,受信者に現在のアソシエーションに属するSCTPパケットを検証し,過去のアソシエーションからの古いパケットではないことを確認することを許す鍵を提供する.
とりあえずこんな感じ.
意味わからんところは随時修正していく.
SCTPを試す
LTEや,LTE Advancedの制御信号の送受信に使われてたり,openflowでサポートされてたりと
最近何かと話題のSCTPを軽く試してみる.
プロトコルの仕様はまだ読み切っていないが,アサーションの生成とデータの送信,アサーションのシャットダウンまでを動かす.
環境:
Ubuntu14.04 LTS 64bit (VMWare Player上で動作)
実行:
端末を2つ開いて,以下のコマンドを実行する.
- server
$ sctp_darn -H 127.0.0.1 -P 2500 -l
- client
$ sctp_darn -H 127.0.0.1 -P 2600 -h 127.0.0.1 -p 2500 -s
クライアント側の端末に,送信する文字列を入力する