diff --git a/cmd/hypervisor/commands/root.go b/cmd/hypervisor/commands/root.go index 0b3046531d..80a29a6b97 100644 --- a/cmd/hypervisor/commands/root.go +++ b/cmd/hypervisor/commands/root.go @@ -1,11 +1,13 @@ package commands import ( + "context" "fmt" - "net" "net/http" "os" + "github.com/SkycoinProject/dmsg" + "github.com/SkycoinProject/dmsg/disc" "github.com/SkycoinProject/skycoin/src/util/logging" "github.com/spf13/cobra" @@ -62,10 +64,22 @@ var rootCmd = &cobra.Command{ log.Infof("serving RPC on '%s'", rpcAddr) go func() { - l, err := net.Listen("tcp", rpcAddr) + _, rpcPort, err := config.Interfaces.SplitRPCAddr() + if err != nil { + log.Fatalln("Failed to parse rpc port from rpc address:", err) + } + + dmsgC := dmsg.NewClient(config.PK, config.SK, disc.NewHTTP(config.DmsgDiscovery)) + + ctx := context.Background() + if err = dmsgC.InitiateServerConnections(ctx, 1); err != nil { + log.Fatalln("failed to initiate dmsg server connections:", err) + } + l, err := dmsgC.Listen(rpcPort) if err != nil { log.Fatalln("Failed to bind tcp port:", err) } + if err := m.ServeRPC(l); err != nil { log.Fatalln("Failed to serve RPC:", err) } diff --git a/cmd/hypervisor/hypervisor.postman_collection.json b/cmd/hypervisor/hypervisor.postman_collection.json index 665b29e9a4..53fe1ffb23 100644 --- a/cmd/hypervisor/hypervisor.postman_collection.json +++ b/cmd/hypervisor/hypervisor.postman_collection.json @@ -1,788 +1,1041 @@ { - "info": { - "_postman_id": "daa8ec31-db75-4e92-b637-c5117644bfa8", - "name": "Skywire Hypervisor", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "/api/nodes", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes" - ] - }, - "description": "Provides a summary of all connected app nodes." - }, - "response": [ - { - "name": "/api/nodes", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 00:43:57 GMT" - }, - { - "key": "Transfer-Encoding", - "value": "chunked" - } - ], - "cookie": [], - "body": "[\n {\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"3fb65ceb-0cd3-484c-8a9c-21617a06c6dd\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"028825991ec52e8f135b9cf9c9f740698644ea2f2144e43a537ad416601ee1d905\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"4cf57b61-8a31-4c8f-b328-b2533978c4e1\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02af5570345c43715442aabdc72de8faecbccc38058fa3be88da8d85afb95762e6\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"0d2d208f-8e10-4bb4-ada5-58ffa4256723\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"034b60e92c40f566e38753fd0e4bc680a0811d25bee949cb5fee4006e42599d6cd\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b1afc8fd-cb62-4993-9b5e-79267cdcf557\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02add975773c2b1429368c961b9159c14de7662f8185ac5cbf173161e4b9f32937\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"43301e4e-594a-422a-b7b1-7a27e39050a8\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"029e32e79f1a57aa42704d3d88618ef8458b12a8f897dbbb7eecec0a411820f7d4\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2d92ce65-8e2f-45b9-be29-3057951f4821\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"037f94a6071e7cb5edd8039cef0269ba43e48ab290e6144c4195d05478d5b446fb\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1046b7a7-50ec-4795-91cd-a2fed648f305\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"021a12b4514cadb248f65cb4c3b3c9eb32f631e1b9470509c44cd05758021cc32a\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"2c3b35b3-866d-4931-b7b5-a67d59e3df42\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03371b181c5faee70eb040c038c006e6642aa432d8072047348ae087519f3cc684\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1744577b-e36b-468f-ba34-93d2614ff6e0\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0289b6e477ebcda18a190e2a545e4606a70abdb724b676a60cea496f3a170334bc\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"c744dd91-d309-451a-b3aa-b452795e6551\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"02de6056801854c18538dde4b1be096f3fae25c7fe9092d86ad3cd9812a4d91630\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"24a6a15c-ae24-4e5d-826f-789d7c564016\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0302f17f7dec96e7750ce771937e689e26ffd9366e7bd4d34832c8572d1d8a320e\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"5011d6cb-0a46-4131-aa2a-a78b2e02e269\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0200730f65fd7b15a184de1d68305f3e7ca813ef7b7678cbead104b59459a44a49\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b5a795d8-ac72-497b-baa3-454adf6e036d\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03fa52ac4e875d61d4e12bee02264b8030b927194e8ecb41ebc7e6e97c1de542e6\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"97b7ff16-a06d-4bb3-b22f-56550ce81bcf\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03bf84c5cd8cdc85406bee299001b6e2991920118a978e186bb9d7f7adf4b9a22b\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"fdb47e4e-64a4-4001-9213-4b7e53560dc1\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"0207ddf45bb57b4ef7a5c7b76b89464677569dcb585cf8627c788f3d44a3870e5e\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b0294a2f-6f57-4f2b-8624-c1ae5b347b31\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"032dbd4f2b2531db9fbd23f3e53365c7ade63d08154025af7d94e7a7b6d715f4d8\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"81579b6e-d8a7-4cab-b2f2-3ba72a8eae83\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"02b4bcabcaaef410f6b9744715a77e8442e7849452e7202a408daccc4b1c63622b\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"bee8e0ad-8190-4c8b-8323-9680bda05580\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"03f2cf69c598c4981a12f665e3b288f9a39d260a883217ed278b0bfc9871faecb4\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"339c3342-0285-454f-b1af-d328a2790767\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"02017acb7de8041df23508a82ed2d49ded03f000d19bc000eb120db80a793664f6\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"8be92ca7-795b-44f6-9c3c-b364cff45bd4\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"03bd2e96d3b56037bfd179b400a5f4953d46467e4913d1c4322c66c1bec11158be\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"03e26b70fa8de90444128d78909e10331683be7d304452def6f88ef13d19e2e22d\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": null\n },\n {\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"f40a8665-8687-461d-971a-2c93d234a449\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"03455586704d340771740533b3b5fff25656877e5f1b9118245e3d7a9f1cd46fb8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"a350e9e0-4cf9-4121-b5a6-65733264f7a4\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"02bcd9e9540b7779b189841baa73cde2aaff4ae734acd4873155d9f578c69eb5d5\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"f7852f53-6758-40c5-b42d-d94331f3d82a\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"0392ff06c76763808a9a3d43e5cdc8dfbbbd01efb7b58c1fc315208498cc95807c\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n }\n]" - } - ] - }, - { - "name": "/api/nodes/{pk}", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02" - ], - "query": [ - { - "key": "", - "value": "", - "disabled": true - } - ] - }, - "description": "Provides a summary of a given connected app node of public key." - }, - "response": [ - { - "name": "/api/nodes/:pk", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2" - ], - "query": [ - { - "key": "", - "value": "", - "disabled": true - } - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 00:47:03 GMT" - }, - { - "key": "Transfer-Encoding", - "value": "chunked" - } - ], - "cookie": [], - "body": "{\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"3fb65ceb-0cd3-484c-8a9c-21617a06c6dd\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"028825991ec52e8f135b9cf9c9f740698644ea2f2144e43a537ad416601ee1d905\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"4cf57b61-8a31-4c8f-b328-b2533978c4e1\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02af5570345c43715442aabdc72de8faecbccc38058fa3be88da8d85afb95762e6\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"0d2d208f-8e10-4bb4-ada5-58ffa4256723\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"034b60e92c40f566e38753fd0e4bc680a0811d25bee949cb5fee4006e42599d6cd\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b1afc8fd-cb62-4993-9b5e-79267cdcf557\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02add975773c2b1429368c961b9159c14de7662f8185ac5cbf173161e4b9f32937\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"43301e4e-594a-422a-b7b1-7a27e39050a8\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"029e32e79f1a57aa42704d3d88618ef8458b12a8f897dbbb7eecec0a411820f7d4\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2d92ce65-8e2f-45b9-be29-3057951f4821\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"037f94a6071e7cb5edd8039cef0269ba43e48ab290e6144c4195d05478d5b446fb\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1046b7a7-50ec-4795-91cd-a2fed648f305\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"021a12b4514cadb248f65cb4c3b3c9eb32f631e1b9470509c44cd05758021cc32a\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n}" - } - ] - }, - { - "name": "/api/nodes/{pk}/apps", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02/apps", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02", - "apps" - ] - }, - "description": "Provides a summary of an AppNode's apps." - }, - "response": [ - { - "name": "/api/nodes/:pk/apps", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2/apps", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2", - "apps" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 00:48:55 GMT" - }, - { - "key": "Content-Length", - "value": "119" - } - ], - "cookie": [], - "body": "[\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n]" - } - ] - }, - { - "name": "/api/nodes/{pk}/apps/{app}", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02/apps/foo.v1.0", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02", - "apps", - "foo.v1.0" - ] - }, - "description": "Starts an app on an AppNode." - }, - "response": [ - { - "name": "/api/nodes/:pk/apps/:app/start", - "originalRequest": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2/apps/foo.v1.0/start", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2", - "apps", - "foo.v1.0", - "start" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 00:50:40 GMT" - }, - { - "key": "Content-Length", - "value": "130" - } - ], - "cookie": [], - "body": "{\n \"node\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"app\": \"foo.v1.0\",\n \"command\": \"StartApp\",\n \"success\": true\n}" - } - ] - }, - { - "name": "/api/nodes/{pk}/apps/{app}", - "request": { - "method": "PUT", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\"autostart\": true,\n\t\"status\": 1\n}" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/apps/foo.v1.0", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "apps", - "foo.v1.0" - ] - }, - "description": "Starts an app on an AppNode." - }, - "response": [ - { - "name": "/api/nodes/{pk}/apps/{app}", - "originalRequest": { - "method": "PUT", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\"autostart\": true,\n\t\"status\": 1\n}" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/apps/foo.v1.0", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "apps", - "foo.v1.0" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Date", - "value": "Sun, 17 Feb 2019 10:37:17 GMT" - }, - { - "key": "Content-Length", - "value": "58" - } - ], - "cookie": [], - "body": "{\n \"name\": \"foo.v1.0\",\n \"autostart\": true,\n \"port\": 10,\n \"status\": 0\n}" - } - ] - }, - { - "name": "/api/nodes/{pk}/transport-types", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transport-types", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "transport-types" - ] - }, - "description": "Lists supported transport types of the given AppNode." - }, - "response": [ - { - "name": "/api/nodes/:pk/transport-types", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transport-types", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", - "transport-types" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 01:14:08 GMT" - }, - { - "key": "Content-Length", - "value": "22" - } - ], - "cookie": [], - "body": "[\n \"messaging\",\n \"native\"\n]" - } - ] - }, - { - "name": "/api/nodes/{pk}/transports", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports?logs=true", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "transports" - ], - "query": [ - { - "key": "logs", - "value": "true", - "description": "whether to show with logs." - } - ] - }, - "description": "List transports of given AppNode." - }, - "response": [ - { - "name": "/api/nodes/:pk/transports", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports?logs=true", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", - "transports" - ], - "query": [ - { - "key": "logs", - "value": "true", - "description": "whether to show with logs." - } - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 01:15:50 GMT" - }, - { - "key": "Transfer-Encoding", - "value": "chunked" - } - ], - "cookie": [], - "body": "[\n {\n \"id\": \"e86f4d67-eb22-4d1c-8c27-8f021051a5cf\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"028684d27d1c9bc36406da560d3f75a295a54ad0649d54eb3437655d8524bbe279\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02a2f9b005ce53b77499e73eb4b67d60807a32d1616615809408150d2ff2631da8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"50142ec9-027d-490d-ba86-e335b6ffffa0\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02d2b79b0e37671e8da948ddb7a51b24096a7b7fe3a64403f78ab031816b3009f3\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"85a60d18-f1a3-45b1-b7cc-8906c95dfdb0\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02c5015450d929bb38c496505f3781d671a11f108cecc0ef6f4a9ff6cf841e5bcf\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"16575562-14c4-492d-9112-dc9f9d3f201d\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"0206ad1343becba521d66ce58b72b2fd8592c998f05ce6fb82a8ab44f3583f9023\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"d0fa7457-e887-406e-ac84-e009fe6df490\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"026202dd7119e8f0635ff1adb52e826fc107472319033db47dbff428b66d3474ae\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"236d2c10-5d92-4d64-b66a-42e2a60ac231\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"020906cf03d1037149150f3d4d06b242d3fa5a3ee6fc25edef6373061176ad5279\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"03c845c9-57b0-4b84-a184-70f952497a8a\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"0254cffd054fa00fa4c89f2b9d2ee3a52b69641bfd4a9e5ce59f5c086adf8d2e1e\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n]" - } - ] - }, - { - "name": "/api/nodes/{pk}/transports", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n\t\"transport_type\": \"native\",\n\t\"public\": true\n}" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "transports" - ] - }, - "description": "Adds a transport to a given AppNode." - }, - "response": [ - { - "name": "POST /api/nodes/transports", - "originalRequest": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n\t\"transport_type\": \"native\",\n\t\"public\": true\n}" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", - "transports" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 01:19:01 GMT" - }, - { - "key": "Content-Length", - "value": "258" - } - ], - "cookie": [], - "body": "{\n \"id\": \"7a4236d4-8ae4-478c-acd7-e3577d730a49\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n}" - } - ] - }, - { - "name": "/api/nodes/{pk}/transports/{tid}", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports/70836b44-f6e5-4c17-a5e8-e1cbef89a10f", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "transports", - "70836b44-f6e5-4c17-a5e8-e1cbef89a10f" - ] - }, - "description": "Obtains summary of transport of given TransportID and AppNode." - }, - "response": [ - { - "name": "/api/nodes/:pk/transports/:tid", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports/2ff2d608-fe14-4c17-938c-3af8afd053ae", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", - "transports", - "2ff2d608-fe14-4c17-938c-3af8afd053ae" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 01:23:06 GMT" - }, - { - "key": "Content-Length", - "value": "261" - } - ], - "cookie": [], - "body": "{\n \"id\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02a2f9b005ce53b77499e73eb4b67d60807a32d1616615809408150d2ff2631da8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n}" - } - ] - }, - { - "name": "DELETE /api/nodes/{pk}/transports/{tid}", - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports/d5ace20e-06c8-4867-bda2-9449459a9e5a", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", - "transports", - "d5ace20e-06c8-4867-bda2-9449459a9e5a" - ] - }, - "description": "Removes transport of given TransportID and AppNode." - }, - "response": [ - { - "name": "DELETE /api/nodes/:pk/transports/:tid", - "originalRequest": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports/2ff2d608-fe14-4c17-938c-3af8afd053ae", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "api", - "nodes", - "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", - "transports", - "2ff2d608-fe14-4c17-938c-3af8afd053ae" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Date", - "value": "Wed, 13 Feb 2019 01:24:20 GMT" - }, - { - "key": "Content-Length", - "value": "171" - } - ], - "cookie": [], - "body": "{\n \"node\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"transport\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"command\": \"RemoveTransport\",\n \"success\": true\n}" - } - ] - } - ] -} + "info": { + "_postman_id": "dfdba35b-6b4f-4658-80e1-d57526f1059f", + "name": "Skywire Hypervisor", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "/api/nodes", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes" + ] + }, + "description": "Provides a summary of all connected app nodes." + }, + "response": [ + { + "name": "/api/nodes", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 00:43:57 GMT" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "[\n {\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"3fb65ceb-0cd3-484c-8a9c-21617a06c6dd\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"028825991ec52e8f135b9cf9c9f740698644ea2f2144e43a537ad416601ee1d905\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"4cf57b61-8a31-4c8f-b328-b2533978c4e1\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02af5570345c43715442aabdc72de8faecbccc38058fa3be88da8d85afb95762e6\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"0d2d208f-8e10-4bb4-ada5-58ffa4256723\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"034b60e92c40f566e38753fd0e4bc680a0811d25bee949cb5fee4006e42599d6cd\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b1afc8fd-cb62-4993-9b5e-79267cdcf557\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02add975773c2b1429368c961b9159c14de7662f8185ac5cbf173161e4b9f32937\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"43301e4e-594a-422a-b7b1-7a27e39050a8\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"029e32e79f1a57aa42704d3d88618ef8458b12a8f897dbbb7eecec0a411820f7d4\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2d92ce65-8e2f-45b9-be29-3057951f4821\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"037f94a6071e7cb5edd8039cef0269ba43e48ab290e6144c4195d05478d5b446fb\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1046b7a7-50ec-4795-91cd-a2fed648f305\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"021a12b4514cadb248f65cb4c3b3c9eb32f631e1b9470509c44cd05758021cc32a\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"2c3b35b3-866d-4931-b7b5-a67d59e3df42\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03371b181c5faee70eb040c038c006e6642aa432d8072047348ae087519f3cc684\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1744577b-e36b-468f-ba34-93d2614ff6e0\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0289b6e477ebcda18a190e2a545e4606a70abdb724b676a60cea496f3a170334bc\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"c744dd91-d309-451a-b3aa-b452795e6551\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"02de6056801854c18538dde4b1be096f3fae25c7fe9092d86ad3cd9812a4d91630\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"24a6a15c-ae24-4e5d-826f-789d7c564016\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0302f17f7dec96e7750ce771937e689e26ffd9366e7bd4d34832c8572d1d8a320e\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"5011d6cb-0a46-4131-aa2a-a78b2e02e269\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"0200730f65fd7b15a184de1d68305f3e7ca813ef7b7678cbead104b59459a44a49\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b5a795d8-ac72-497b-baa3-454adf6e036d\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03fa52ac4e875d61d4e12bee02264b8030b927194e8ecb41ebc7e6e97c1de542e6\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"97b7ff16-a06d-4bb3-b22f-56550ce81bcf\",\n \"local_pk\": \"03d9ea0420cb9750b475e23f3f629a0eb521f9d94e1cc544abd76b87bf42ad71a5\",\n \"remote_pk\": \"03bf84c5cd8cdc85406bee299001b6e2991920118a978e186bb9d7f7adf4b9a22b\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"fdb47e4e-64a4-4001-9213-4b7e53560dc1\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"0207ddf45bb57b4ef7a5c7b76b89464677569dcb585cf8627c788f3d44a3870e5e\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b0294a2f-6f57-4f2b-8624-c1ae5b347b31\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"032dbd4f2b2531db9fbd23f3e53365c7ade63d08154025af7d94e7a7b6d715f4d8\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"81579b6e-d8a7-4cab-b2f2-3ba72a8eae83\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"02b4bcabcaaef410f6b9744715a77e8442e7849452e7202a408daccc4b1c63622b\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"bee8e0ad-8190-4c8b-8323-9680bda05580\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"03f2cf69c598c4981a12f665e3b288f9a39d260a883217ed278b0bfc9871faecb4\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"339c3342-0285-454f-b1af-d328a2790767\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"02017acb7de8041df23508a82ed2d49ded03f000d19bc000eb120db80a793664f6\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"8be92ca7-795b-44f6-9c3c-b364cff45bd4\",\n \"local_pk\": \"0301b27adf2954a9f97c443c478e48253a707e7b467d0c0c0ba7a2091fa8ec6145\",\n \"remote_pk\": \"03bd2e96d3b56037bfd179b400a5f4953d46467e4913d1c4322c66c1bec11158be\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n },\n {\n \"local_pk\": \"03e26b70fa8de90444128d78909e10331683be7d304452def6f88ef13d19e2e22d\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": null\n },\n {\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"f40a8665-8687-461d-971a-2c93d234a449\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"03455586704d340771740533b3b5fff25656877e5f1b9118245e3d7a9f1cd46fb8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"a350e9e0-4cf9-4121-b5a6-65733264f7a4\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"02bcd9e9540b7779b189841baa73cde2aaff4ae734acd4873155d9f578c69eb5d5\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"f7852f53-6758-40c5-b42d-d94331f3d82a\",\n \"local_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"remote_pk\": \"0392ff06c76763808a9a3d43e5cdc8dfbbbd01efb7b58c1fc315208498cc95807c\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n }\n]" + } + ] + }, + { + "name": "/api/nodes/{pk}", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02?", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + }, + "description": "Provides a summary of a given connected app node of public key." + }, + "response": [ + { + "name": "/api/nodes/:pk", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2?", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 00:47:03 GMT" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "{\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"apps\": [\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n ],\n \"transports\": [\n {\n \"id\": \"3fb65ceb-0cd3-484c-8a9c-21617a06c6dd\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"028825991ec52e8f135b9cf9c9f740698644ea2f2144e43a537ad416601ee1d905\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"4cf57b61-8a31-4c8f-b328-b2533978c4e1\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02af5570345c43715442aabdc72de8faecbccc38058fa3be88da8d85afb95762e6\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"0d2d208f-8e10-4bb4-ada5-58ffa4256723\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"034b60e92c40f566e38753fd0e4bc680a0811d25bee949cb5fee4006e42599d6cd\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"b1afc8fd-cb62-4993-9b5e-79267cdcf557\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"02add975773c2b1429368c961b9159c14de7662f8185ac5cbf173161e4b9f32937\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"43301e4e-594a-422a-b7b1-7a27e39050a8\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"029e32e79f1a57aa42704d3d88618ef8458b12a8f897dbbb7eecec0a411820f7d4\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2d92ce65-8e2f-45b9-be29-3057951f4821\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"037f94a6071e7cb5edd8039cef0269ba43e48ab290e6144c4195d05478d5b446fb\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"1046b7a7-50ec-4795-91cd-a2fed648f305\",\n \"local_pk\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"remote_pk\": \"021a12b4514cadb248f65cb4c3b3c9eb32f631e1b9470509c44cd05758021cc32a\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n ]\n}" + } + ] + }, + { + "name": "/api/nodes/{pk}/apps", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02/apps", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02", + "apps" + ] + }, + "description": "Provides a summary of an AppNode's apps." + }, + "response": [ + { + "name": "/api/nodes/:pk/apps", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2/apps", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2", + "apps" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 00:48:55 GMT" + }, + { + "key": "Content-Length", + "value": "119" + } + ], + "cookie": [], + "body": "[\n {\n \"name\": \"foo.v1.0\",\n \"autostart\": false,\n \"port\": 10,\n \"status\": 0\n },\n {\n \"name\": \"bar.v2.0\",\n \"autostart\": false,\n \"port\": 20,\n \"status\": 0\n }\n]" + } + ] + }, + { + "name": "/api/nodes/{pk}/apps/{app}", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02/apps/foo.v1.0", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "021c535e45756c63151820c8f31bfbb0efd6d7d49305e133e1650aae889d60ff02", + "apps", + "foo.v1.0" + ] + }, + "description": "Starts an app on an AppNode." + }, + "response": [ + { + "name": "/api/nodes/:pk/apps/:app/start", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2/apps/foo.v1.0/start", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2", + "apps", + "foo.v1.0", + "start" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 00:50:40 GMT" + }, + { + "key": "Content-Length", + "value": "130" + } + ], + "cookie": [], + "body": "{\n \"node\": \"02500488fc25814e55e6c740537ed14ca677aebe8a883681bae718a36516a7b0a2\",\n \"app\": \"foo.v1.0\",\n \"command\": \"StartApp\",\n \"success\": true\n}" + } + ] + }, + { + "name": "/api/nodes/{pk}/apps/{app}", + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"autostart\": true,\n\t\"status\": 1\n}" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/apps/foo.v1.0", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "apps", + "foo.v1.0" + ] + }, + "description": "Starts an app on an AppNode." + }, + "response": [ + { + "name": "/api/nodes/{pk}/apps/{app}", + "originalRequest": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"autostart\": true,\n\t\"status\": 1\n}" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/apps/foo.v1.0", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "apps", + "foo.v1.0" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 17 Feb 2019 10:37:17 GMT" + }, + { + "key": "Content-Length", + "value": "58" + } + ], + "cookie": [], + "body": "{\n \"name\": \"foo.v1.0\",\n \"autostart\": true,\n \"port\": 10,\n \"status\": 0\n}" + } + ] + }, + { + "name": "/api/nodes/{pk}/transport-types", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transport-types", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "transport-types" + ] + }, + "description": "Lists supported transport types of the given AppNode." + }, + "response": [ + { + "name": "/api/nodes/:pk/transport-types", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transport-types", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", + "transport-types" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 01:14:08 GMT" + }, + { + "key": "Content-Length", + "value": "22" + } + ], + "cookie": [], + "body": "[\n \"messaging\",\n \"native\"\n]" + } + ] + }, + { + "name": "/api/nodes/{pk}/transports", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports?logs=true", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "transports" + ], + "query": [ + { + "key": "logs", + "value": "true", + "description": "whether to show with logs." + } + ] + }, + "description": "List transports of given AppNode." + }, + "response": [ + { + "name": "/api/nodes/:pk/transports", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports?logs=true", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", + "transports" + ], + "query": [ + { + "key": "logs", + "value": "true", + "description": "whether to show with logs." + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 01:15:50 GMT" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"e86f4d67-eb22-4d1c-8c27-8f021051a5cf\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"028684d27d1c9bc36406da560d3f75a295a54ad0649d54eb3437655d8524bbe279\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02a2f9b005ce53b77499e73eb4b67d60807a32d1616615809408150d2ff2631da8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"50142ec9-027d-490d-ba86-e335b6ffffa0\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02d2b79b0e37671e8da948ddb7a51b24096a7b7fe3a64403f78ab031816b3009f3\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"85a60d18-f1a3-45b1-b7cc-8906c95dfdb0\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02c5015450d929bb38c496505f3781d671a11f108cecc0ef6f4a9ff6cf841e5bcf\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"16575562-14c4-492d-9112-dc9f9d3f201d\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"0206ad1343becba521d66ce58b72b2fd8592c998f05ce6fb82a8ab44f3583f9023\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"d0fa7457-e887-406e-ac84-e009fe6df490\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"026202dd7119e8f0635ff1adb52e826fc107472319033db47dbff428b66d3474ae\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"236d2c10-5d92-4d64-b66a-42e2a60ac231\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"020906cf03d1037149150f3d4d06b242d3fa5a3ee6fc25edef6373061176ad5279\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n },\n {\n \"id\": \"03c845c9-57b0-4b84-a184-70f952497a8a\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"0254cffd054fa00fa4c89f2b9d2ee3a52b69641bfd4a9e5ce59f5c086adf8d2e1e\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n }\n]" + } + ] + }, + { + "name": "/api/nodes/{pk}/transports", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n\t\"transport_type\": \"native\",\n\t\"public\": true\n}" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "transports" + ] + }, + "description": "Adds a transport to a given AppNode." + }, + "response": [ + { + "name": "POST /api/nodes/transports", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n\t\"transport_type\": \"native\",\n\t\"public\": true\n}" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", + "transports" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 01:19:01 GMT" + }, + { + "key": "Content-Length", + "value": "258" + } + ], + "cookie": [], + "body": "{\n \"id\": \"7a4236d4-8ae4-478c-acd7-e3577d730a49\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"03c497380efd87e19208bb484ee322ede1e091b2a0b653e6d25475f641602376a9\",\n \"type\": \"native\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n}" + } + ] + }, + { + "name": "/api/nodes/{pk}/transports/{tid}", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports/70836b44-f6e5-4c17-a5e8-e1cbef89a10f", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "transports", + "70836b44-f6e5-4c17-a5e8-e1cbef89a10f" + ] + }, + "description": "Obtains summary of transport of given TransportID and AppNode." + }, + "response": [ + { + "name": "/api/nodes/:pk/transports/:tid", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports/2ff2d608-fe14-4c17-938c-3af8afd053ae", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", + "transports", + "2ff2d608-fe14-4c17-938c-3af8afd053ae" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 01:23:06 GMT" + }, + { + "key": "Content-Length", + "value": "261" + } + ], + "cookie": [], + "body": "{\n \"id\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"local_pk\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"remote_pk\": \"02a2f9b005ce53b77499e73eb4b67d60807a32d1616615809408150d2ff2631da8\",\n \"type\": \"messaging\",\n \"log\": {\n \"received\": null,\n \"sent\": null\n }\n}" + } + ] + }, + { + "name": "DELETE /api/nodes/{pk}/transports/{tid}", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64/transports/d5ace20e-06c8-4867-bda2-9449459a9e5a", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "023ab9f45c0eb3625f9848a9ff6822c6d0965a94d3e7955f1869f38153df0e5b64", + "transports", + "d5ace20e-06c8-4867-bda2-9449459a9e5a" + ] + }, + "description": "Removes transport of given TransportID and AppNode." + }, + "response": [ + { + "name": "DELETE /api/nodes/:pk/transports/:tid", + "originalRequest": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/api/nodes/039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2/transports/2ff2d608-fe14-4c17-938c-3af8afd053ae", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2", + "transports", + "2ff2d608-fe14-4c17-938c-3af8afd053ae" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Wed, 13 Feb 2019 01:24:20 GMT" + }, + { + "key": "Content-Length", + "value": "171" + } + ], + "cookie": [], + "body": "{\n \"node\": \"039337a306ffbd6a7495f79b65aec91ce65756e4fd1cb2cd726840b2eee4fa59c2\",\n \"transport\": \"2ff2d608-fe14-4c17-938c-3af8afd053ae\",\n \"command\": \"RemoveTransport\",\n \"success\": true\n}" + } + ] + }, + { + "name": "http://localhost:8080/api/create-account", + "request": { + "method": "POST", + "header": [ + { + "key": "", + "value": "", + "type": "text", + "disabled": true + }, + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"username\":\"admin\", \"password\":\"123456\"}" + }, + "url": { + "raw": "http://localhost:8080/api/create-account", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "create-account" + ] + } + }, + "response": [ + { + "name": "http://localhost:8080/api/create-account", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "", + "value": "", + "type": "text", + "disabled": true + }, + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"username\":\"admin\", \"password\":\"123456\"}" + }, + "url": { + "raw": "http://localhost:8080/api/login", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "login" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Set-Cookie", + "value": "swm-session=MTU2NjkxNjE0N3xRZUlIRXpMRGwzWlNwNE01QzE0WnAxd3ZEb3pvNEZLSEhCYjd0eWI4dzZhWFEzWHRTUTdRQkVyTUI5cHVoOExGX0ttODJfMWF8AIoAT1RkzoPxb38uTg67eDdz26QqWIdvM_9lEXWCt8Q=; Expires=Wed, 28 Aug 2019 02:29:07 GMT; HttpOnly; Secure; SameSite" + }, + { + "key": "Date", + "value": "Tue, 27 Aug 2019 14:29:07 GMT" + }, + { + "key": "Content-Length", + "value": "5" + } + ], + "cookie": [], + "body": "true" + } + ] + }, + { + "name": "/api/nodes/{pk}/uptime", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/uptime", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "uptime" + ] + }, + "description": "Provides given node's uptime in seconds" + }, + "response": [ + { + "name": "/api/nodes/{pk}/uptime", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/uptime", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "uptime" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 10 Sep 2019 09:30:53 GMT" + }, + { + "key": "Content-Length", + "value": "13" + } + ], + "cookie": [], + "body": "12.846401599" + } + ] + }, + { + "name": "http://localhost:8080/api/nodes/{pk}/health", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/health", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "health" + ] + }, + "description": "Returns health information about the requested visor" + }, + "response": [ + { + "name": "http://localhost:8080/api/nodes/{pk}/health", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/health", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "health" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 10 Sep 2019 09:40:08 GMT" + }, + { + "key": "Content-Length", + "value": "77" + } + ], + "cookie": [], + "body": "{\n \"status\": 200,\n \"transport_discovery\": 200,\n \"route_finder\": 200,\n \"setup_node\": 200\n}" + } + ] + }, + { + "name": "http://localhost:8080/api/nodes/{pk}/apps/{app}/logs?since={timestamp}", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/apps/skychat/logs?since=2019-09-10T11:30:41.097351631+02:00", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "apps", + "skychat", + "logs" + ], + "query": [ + { + "key": "since", + "value": "2019-09-10T11:30:41.097351631+02:00" + } + ] + }, + "description": "Returns given app's logs in given node since given timestamp. The given timestamp log is not included in the results.\n\nFor optimal performance, the last request's timestamp should be used in the next request as value for since.\n\nIf there is an error in the timestamp format or since is empty all the logs from the beginning will be returned." + }, + "response": [ + { + "name": "http://localhost:8080/api/nodes/{pk}/apps/{app}/logs?since={timestamp}", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/api/nodes/024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7/apps/skychat/logs?since=2019-09-10T11:30:41.097351631+02:00", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "nodes", + "024ec47420176680816e0406250e7156465e4531f5b26057c9f6297bb0303558c7", + "apps", + "skychat", + "logs" + ], + "query": [ + { + "key": "since", + "value": "2019-09-10T11:30:41.097351631+02:00" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 10 Sep 2019 10:25:28 GMT" + }, + { + "key": "Content-Length", + "value": "216" + } + ], + "cookie": [], + "body": "{\n \"last_log_timestamp\": \"2019-09-10T12:23:33.916965349+02:00\",\n \"logs\": [\n \"[2019-09-10T12:13:48.532319632+02:00] INFO []: Serving HTTP on :8000\\n\",\n \"[2019-09-10T12:23:33.916965349+02:00] INFO []: Serving HTTP on :8000\\n\"\n ]\n}" + } + ] + } + ] +} \ No newline at end of file diff --git a/go.sum b/go.sum index bea634b844..9e3a058a86 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/SkycoinProject/dmsg v0.0.0-20190918162505-cc37af88b8bf/go.mod h1:WiVS8uAqzFsuWcRlDBsjrxqAiD41ftxS7S7CDTXZpko= github.com/SkycoinProject/dmsg v0.0.0-20190918181704-b7cccca1451e h1:JMIfHAjNSJLvKdnwXpUudbnYG627qD5d6aye+gmDups= github.com/SkycoinProject/dmsg v0.0.0-20190918181704-b7cccca1451e/go.mod h1:iB171maaQybaYptTK/mhzb02uonVRKQ8oCsJ7blquRw= github.com/SkycoinProject/skycoin v0.26.0 h1:8/ZRZb2VM2DM4YTIitRJMZ3Yo/3H1FFmbCMx5o6ekmA= @@ -158,6 +157,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190627182818-9947fec5c3ab/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= diff --git a/pkg/app/log_store_test.go b/pkg/app/log_store_test.go index 8ff172d1fb..b1f7556f25 100644 --- a/pkg/app/log_store_test.go +++ b/pkg/app/log_store_test.go @@ -29,7 +29,6 @@ func TestLogStore(t *testing.T) { require.NoError(t, err) err = ls.Store(t1, "bar") - fmt.Println("original: ", t1.Format(time.RFC3339Nano)) require.NoError(t, err) t2, err := time.Parse(time.RFC3339, "2000-02-01T00:00:00Z") diff --git a/pkg/hypervisor/config.go b/pkg/hypervisor/config.go index b49dad3b5e..278c097f24 100644 --- a/pkg/hypervisor/config.go +++ b/pkg/hypervisor/config.go @@ -4,8 +4,10 @@ import ( "encoding/hex" "encoding/json" "net/http" + "net/url" "os" "path/filepath" + "strconv" "time" "github.com/SkycoinProject/dmsg/cipher" @@ -35,12 +37,13 @@ func (hk *Key) UnmarshalText(text []byte) error { // Config configures the hypervisor. type Config struct { - PK cipher.PubKey `json:"public_key"` - SK cipher.SecKey `json:"secret_key"` - DBPath string `json:"db_path"` // Path to store database file. - EnableAuth bool `json:"enable_auth"` // Whether to enable user management. - Cookies CookieConfig `json:"cookies"` // Configures cookies (for session management). - Interfaces InterfaceConfig `json:"interfaces"` // Configures exposed interfaces. + PK cipher.PubKey `json:"public_key"` + SK cipher.SecKey `json:"secret_key"` + DBPath string `json:"db_path"` // Path to store database file. + EnableAuth bool `json:"enable_auth"` // Whether to enable user management. + Cookies CookieConfig `json:"cookies"` // Configures cookies (for session management). + Interfaces InterfaceConfig `json:"interfaces"` // Configures exposed interfaces. + DmsgDiscovery string `json:"dmsg_discovery"` // DmsgDiscovery address for dmsg usage } func makeConfig() Config { @@ -134,3 +137,18 @@ func (c *InterfaceConfig) FillDefaults() { c.HTTPAddr = ":8080" c.RPCAddr = ":7080" } + +// SplitRPCAddr returns host and port and whatever error results from parsing the rpc address interface +func (c *InterfaceConfig) SplitRPCAddr() (host string, port uint16, err error) { + addr, err := url.Parse(c.RPCAddr) + if err != nil { + return + } + + uint64port, err := strconv.ParseUint(addr.Port(), 10, 16) + if err != nil { + return + } + + return addr.Host, uint16(uint64port), nil +} diff --git a/pkg/hypervisor/hypervisor.go b/pkg/hypervisor/hypervisor.go index bd8049586c..cc41dc13f5 100644 --- a/pkg/hypervisor/hypervisor.go +++ b/pkg/hypervisor/hypervisor.go @@ -6,23 +6,23 @@ import ( "errors" "fmt" "math/rand" - "net" "net/http" "net/rpc" "strconv" + "strings" "sync" "time" - "github.com/go-chi/chi" - "github.com/go-chi/chi/middleware" - "github.com/google/uuid" + "github.com/SkycoinProject/dmsg" "github.com/SkycoinProject/dmsg/cipher" - "github.com/SkycoinProject/dmsg/noise" "github.com/SkycoinProject/skycoin/src/util/logging" "github.com/SkycoinProject/skywire-mainnet/pkg/app" "github.com/SkycoinProject/skywire-mainnet/pkg/httputil" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" "github.com/SkycoinProject/skywire-mainnet/pkg/visor" + "github.com/go-chi/chi" + "github.com/go-chi/chi/middleware" + "github.com/google/uuid" ) var ( @@ -31,7 +31,7 @@ var ( ) type appNodeConn struct { - Addr *noise.Addr + Addr dmsg.Addr Client visor.RPCClient } @@ -60,13 +60,13 @@ func NewNode(config Config) (*Node, error) { } // ServeRPC serves RPC of a Node. -func (m *Node) ServeRPC(lis net.Listener) error { +func (m *Node) ServeRPC(lis *dmsg.Listener) error { for { - conn, err := noise.WrapListener(lis, m.c.PK, m.c.SK, false, noise.HandshakeXK).Accept() + conn, err := lis.Accept() if err != nil { return err } - addr := conn.RemoteAddr().(*noise.Addr) + addr := conn.RemoteAddr().(dmsg.Addr) m.mu.Lock() m.nodes[addr.PK] = appNodeConn{ Addr: addr, @@ -99,9 +99,9 @@ func (m *Node) AddMockData(config MockConfig) error { } m.mu.Lock() m.nodes[pk] = appNodeConn{ - Addr: &noise.Addr{ + Addr: dmsg.Addr{ PK: pk, - Addr: mockAddr(fmt.Sprintf("0.0.0.0:%d", i)), + Port: uint16(i), }, Client: client, } @@ -245,7 +245,7 @@ func (m *Node) getNodes() http.HandlerFunc { summary = &visor.Summary{PubKey: pk} } summaries = append(summaries, summaryResp{ - TCPAddr: c.Addr.Addr.String(), + TCPAddr: c.Addr.String(), Summary: summary, }) } @@ -263,7 +263,7 @@ func (m *Node) getNode() http.HandlerFunc { return } httputil.WriteJSON(w, r, http.StatusOK, summaryResp{ - TCPAddr: ctx.Addr.Addr.String(), + TCPAddr: ctx.Addr.String(), Summary: summary, }) }) @@ -337,6 +337,7 @@ type LogsRes struct { func (m *Node) appLogsSince() http.HandlerFunc { return m.withCtx(m.appCtx, func(w http.ResponseWriter, r *http.Request, ctx *httpCtx) { since := r.URL.Query().Get("since") + since = strings.Replace(since, " ", "+", 1) // we need to put '+' again that was replaced in the query string // if time is not parseable or empty default to return all logs t, err := time.Parse(time.RFC3339Nano, since) @@ -572,7 +573,7 @@ func (m *Node) getLoops() http.HandlerFunc { <<< Helper functions >>> */ -func (m *Node) client(pk cipher.PubKey) (*noise.Addr, visor.RPCClient, bool) { +func (m *Node) client(pk cipher.PubKey) (dmsg.Addr, visor.RPCClient, bool) { m.mu.RLock() conn, ok := m.nodes[pk] m.mu.RUnlock() @@ -582,7 +583,7 @@ func (m *Node) client(pk cipher.PubKey) (*noise.Addr, visor.RPCClient, bool) { type httpCtx struct { // Node PK cipher.PubKey - Addr *noise.Addr + Addr dmsg.Addr RPC visor.RPCClient // App diff --git a/pkg/setup/idreservoir.go b/pkg/setup/idreservoir.go index 9f21b99abb..6f7c567a22 100644 --- a/pkg/setup/idreservoir.go +++ b/pkg/setup/idreservoir.go @@ -9,7 +9,6 @@ import ( "time" "github.com/SkycoinProject/dmsg/cipher" - "github.com/SkycoinProject/skywire-mainnet/pkg/routing" ) diff --git a/pkg/setup/node.go b/pkg/setup/node.go index bcf65763cd..fd47e83878 100644 --- a/pkg/setup/node.go +++ b/pkg/setup/node.go @@ -12,9 +12,9 @@ import ( "github.com/SkycoinProject/dmsg/disc" "github.com/SkycoinProject/skycoin/src/util/logging" - "github.com/SkycoinProject/skywire-mainnet/pkg/snet" "github.com/SkycoinProject/skywire-mainnet/pkg/metrics" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" + "github.com/SkycoinProject/skywire-mainnet/pkg/snet" ) // Node performs routes setup operations over messaging channel. diff --git a/pkg/setup/node_test.go b/pkg/setup/node_test.go index d1bb46964c..613111b10e 100644 --- a/pkg/setup/node_test.go +++ b/pkg/setup/node_test.go @@ -12,15 +12,14 @@ import ( "testing" "time" -"github.com/SkycoinProject/dmsg" -"github.com/SkycoinProject/dmsg/cipher" + "github.com/SkycoinProject/dmsg" + "github.com/SkycoinProject/dmsg/cipher" "github.com/SkycoinProject/dmsg/disc" - "github.com/stretchr/testify/require" - "golang.org/x/net/nettest" - "github.com/SkycoinProject/skywire-mainnet/pkg/metrics" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" "github.com/SkycoinProject/skywire-mainnet/pkg/snet" + "github.com/stretchr/testify/require" + "golang.org/x/net/nettest" "github.com/SkycoinProject/skycoin/src/util/logging" ) diff --git a/pkg/visor/config.go b/pkg/visor/config.go index 5727b47129..d56c5160dc 100644 --- a/pkg/visor/config.go +++ b/pkg/visor/config.go @@ -167,7 +167,7 @@ func ensureDir(path string) (string, error) { // HypervisorConfig represents hypervisor configuration. type HypervisorConfig struct { PubKey cipher.PubKey `json:"public_key"` - Addr string `json:"address"` + Port uint16 `json:"port"` } // DmsgConfig represents dmsg configuration. diff --git a/pkg/visor/rpc_client.go b/pkg/visor/rpc_client.go index 0c9f271b0b..7c57c174dc 100644 --- a/pkg/visor/rpc_client.go +++ b/pkg/visor/rpc_client.go @@ -2,20 +2,30 @@ package visor import ( "encoding/binary" + "errors" "fmt" - "github.com/SkycoinProject/skywire-mainnet/pkg/router" "math/rand" + "net" "net/http" "net/rpc" "sync" "time" - "github.com/google/uuid" + "github.com/SkycoinProject/dmsg" "github.com/SkycoinProject/dmsg/cipher" "github.com/SkycoinProject/skycoin/src/util/logging" "github.com/SkycoinProject/skywire-mainnet/pkg/app" + "github.com/SkycoinProject/skywire-mainnet/pkg/router" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" + "github.com/SkycoinProject/skywire-mainnet/pkg/snet" "github.com/SkycoinProject/skywire-mainnet/pkg/transport" + "github.com/google/uuid" +) + +var ( + // ErrAlreadyServing is returned when an operation fails due to an operation + // that is currently running. + ErrAlreadyServing = errors.New("already serving") ) // RPCClient represents a RPC Client implementation. @@ -212,6 +222,103 @@ func (rc *rpcClient) Loops() ([]LoopInfo, error) { return loops, err } +// RPCClientDialer keeps track of an rpc connection and retries to connect if it fails at some point +type RPCClientDialer struct { + dialer *snet.Network + pk cipher.PubKey + port uint16 + conn net.Conn + mu sync.Mutex + done chan struct{} // nil: loop is not running, non-nil: loop is running. +} + +// NewRPCClientDialer creates a new RPCDialer to the given address +func NewRPCClientDialer(dialer *snet.Network, pk cipher.PubKey, port uint16) *RPCClientDialer { + return &RPCClientDialer{ + dialer: dialer, + pk: pk, + port: port, + } +} + +// Run repeatedly dials to remote until a successful connection is established. +// It exposes a RPC Server. +// It will return if Close is called or crypto fails. +func (d *RPCClientDialer) Run(srv *rpc.Server, retry time.Duration) error { + if ok := d.setDone(); !ok { + return ErrAlreadyServing + } + for { + if err := d.establishConn(); err != nil { + // Only return if not network error. + if err != dmsg.ErrRequestRejected { + return err + } + } else { + // Only serve when then dial succeeds. + srv.ServeConn(d.conn) + d.setConn(nil) + } + select { + case <-d.done: + d.clearDone() + return nil + case <-time.After(retry): + } + } +} + +// Close closes the handler. +func (d *RPCClientDialer) Close() (err error) { + if d == nil { + return nil + } + d.mu.Lock() + if d.done != nil { + close(d.done) + } + if d.conn != nil { + err = d.conn.Close() + } + d.mu.Unlock() + return +} + +// This operation should be atomic, hence protected by mutex. +func (d *RPCClientDialer) establishConn() error { + d.mu.Lock() + defer d.mu.Unlock() + + conn, err := d.dialer.Dial(snet.DmsgType, d.pk, d.port) + if err != nil { + return err + } + + d.conn = conn + return nil +} + +func (d *RPCClientDialer) setConn(conn net.Conn) { + d.mu.Lock() + d.conn = conn + d.mu.Unlock() +} + +func (d *RPCClientDialer) setDone() (ok bool) { + d.mu.Lock() + if ok = d.done == nil; ok { + d.done = make(chan struct{}) + } + d.mu.Unlock() + return +} + +func (d *RPCClientDialer) clearDone() { + d.mu.Lock() + d.done = nil + d.mu.Unlock() +} + // MockRPCClient mocks RPCClient. type mockRPCClient struct { startedAt time.Time diff --git a/pkg/visor/rpc_test.go b/pkg/visor/rpc_test.go index ca1a694b20..3d9c64df61 100644 --- a/pkg/visor/rpc_test.go +++ b/pkg/visor/rpc_test.go @@ -134,6 +134,109 @@ func TestStartStopApp(t *testing.T) { node.startedMu.Unlock() } +type TestRPC struct{} + +type AddIn struct{ A, B int } + +func (r *TestRPC) Add(in *AddIn, out *int) error { + *out = in.A + in.B + return nil +} + +// TODO: Implement correctly +/* +func TestRPCClientDialer(t *testing.T) { + svr := rpc.NewServer() + require.NoError(t, svr.Register(new(TestRPC))) + + lPK, lSK := cipher.GenerateKeyPair() + var l *snet.Listener + var port uint16 + var listenerN *snet.Network + discMock := disc.NewMock() + + sPK, sSK := cipher.GenerateKeyPair() + sl, err := net.Listen("tcp", ":0") + require.NoError(t, err) + log.Info("here: ", sl.Addr().String()) + server, err := dmsg.NewServer(sPK, sSK, fmt.Sprintf(":%d", sl.Addr().(*net.TCPAddr).Port), sl, discMock) + require.NoError(t, err) + go func() { + log.Fatal("server error is !!!!!!!!!1 ---->>> ", server.Serve()) + }() + + setup := func() { + var err error + + listenerN = snet.NewRaw(snet.Config{ + PubKey: lPK, + SecKey: lSK, + TpNetworks: []string{snet.DmsgType}, + DmsgMinSrvs: 1, + }, dmsg.NewClient(lPK, lSK, discMock), nil) + + require.NoError(t, listenerN.Init(context.Background())) + l, err = listenerN.Listen(snet.DmsgType, 9999) + require.NoError(t, err) + + lAddr := l.Addr().(dmsg.Addr).String() + t.Logf("Listening on %s", lAddr) + + port = l.Addr().(dmsg.Addr).Port + } + + teardown := func() { + require.NoError(t, l.Close()) + require.NoError(t, listenerN.Close()) + l = nil + } + + t.Run("RunRetry", func(t *testing.T) { + setup() + defer teardown() // Just in case of failure. + + const reconCount = 5 + const retry = time.Second / 4 + + dPK, dSK := cipher.GenerateKeyPair() + n := snet.NewRaw(snet.Config{ + PubKey: dPK, + SecKey: dSK, + TpNetworks: []string{snet.DmsgType}, + DmsgMinSrvs: 1, + }, dmsg.NewClient(dPK, dSK, discMock), nil) + require.NoError(t, n.Init(context.Background())) + + d := NewRPCClientDialer(n, lPK, port) + dDone := make(chan error, 1) + + go func() { + err := d.Run(svr, retry) + dDone <- err + close(dDone) + }() + + for i := 0; i < reconCount; i++ { + teardown() + time.Sleep(retry * 2) // Dialer shouldn't quit retrying in this time. + setup() + + conn, err := l.Accept() + require.NoError(t, err) + + in, out := &AddIn{A: i, B: i}, new(int) + require.NoError(t, rpc.NewClient(conn).Call("TestRPC.Add", in, out)) + require.Equal(t, in.A+in.B, *out) + require.NoError(t, conn.Close()) // NOTE: also closes d, as it's the same connection + } + + // The same connection is closed above (conn.Close()), and hence, this may return an error. + _ = d.Close() // nolint: errcheck + require.NoError(t, <-dDone) + }) +} +/* + /* TODO(evanlinjin): Fix these tests. These tests have been commented out for the following reasons: diff --git a/pkg/visor/visor.go b/pkg/visor/visor.go index ddb7016a09..1c856b025a 100644 --- a/pkg/visor/visor.go +++ b/pkg/visor/visor.go @@ -19,11 +19,10 @@ import ( "syscall" "time" - "github.com/SkycoinProject/skywire-mainnet/pkg/snet" - "github.com/SkycoinProject/dmsg/cipher" "github.com/SkycoinProject/dmsg" - "github.com/SkycoinProject/dmsg/noise" + "github.com/SkycoinProject/dmsg/cipher" "github.com/SkycoinProject/skycoin/src/util/logging" + "github.com/SkycoinProject/skywire-mainnet/pkg/snet" "github.com/SkycoinProject/skywire-mainnet/pkg/app" routeFinder "github.com/SkycoinProject/skywire-mainnet/pkg/route-finder/client" @@ -108,7 +107,7 @@ type Node struct { pidMu sync.Mutex rpcListener net.Listener - rpcDialers []*noise.RPCClientDialer + rpcDialers []*RPCClientDialer } // NewNode constructs new Node. @@ -206,14 +205,10 @@ func NewNode(config *Config, masterLogger *logging.MasterLogger) (*Node, error) } node.rpcListener = l } - node.rpcDialers = make([]*noise.RPCClientDialer, len(config.Hypervisors)) + + node.rpcDialers = make([]*RPCClientDialer, len(config.Hypervisors)) for i, entry := range config.Hypervisors { - node.rpcDialers[i] = noise.NewRPCClientDialer(entry.Addr, noise.HandshakeXK, noise.Config{ - LocalPK: pk, - LocalSK: sk, - RemotePK: entry.PubKey, - Initiator: true, - }) + node.rpcDialers[i] = NewRPCClientDialer(node.n, entry.PubKey, entry.Port) } return node, err @@ -247,9 +242,9 @@ func (node *Node) Start() error { go rpcSvr.Accept(node.rpcListener) } for _, dialer := range node.rpcDialers { - go func(dialer *noise.RPCClientDialer) { + go func(dialer *RPCClientDialer) { if err := dialer.Run(rpcSvr, time.Second); err != nil { - node.logger.Errorf("Dialer exited with error: %v", err) + node.logger.Errorf("Hypervisor dmsg Dial exited with error: %v", err) } }(dialer) } @@ -333,13 +328,6 @@ func (node *Node) Close() (err error) { node.logger.Info("RPC interface stopped successfully") } } - for i, dialer := range node.rpcDialers { - if err = dialer.Close(); err != nil { - node.logger.WithError(err).Errorf("(%d) failed to stop RPC dialer", i) - } else { - node.logger.Infof("(%d) RPC dialer closed successfully", i) - } - } node.startedMu.Lock() for a, bind := range node.startedApps { if err = node.stopApp(a, bind); err != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 8df6b4d95c..e54201d7fd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2,8 +2,8 @@ github.com/SkycoinProject/dmsg/cipher github.com/SkycoinProject/dmsg github.com/SkycoinProject/dmsg/disc -github.com/SkycoinProject/dmsg/noise github.com/SkycoinProject/dmsg/ioutil +github.com/SkycoinProject/dmsg/noise # github.com/SkycoinProject/skycoin v0.26.0 github.com/SkycoinProject/skycoin/src/util/logging github.com/SkycoinProject/skycoin/src/cipher