使用API​​在Azure区块链工作台中创建合同

时间:2019-02-14 15:34:07

标签: node.js azure axios azure-api-apps azure-blockchain-workbench

我正尝试使用axios包从Node.js使用工作台api创建新的合约实例:

首先,我根据docs的请求创建了服务主体,用于获取承载令牌并访问api资源。

然后,对/ api / v1 / applications / workflows /执行GET请求,并获得以下结果:

{
    "id": 27,
    "name": "ScompCertificados",
    "description": "Manejo del flujo de la aplicación Scomp",
    "displayName": "Scomp certificados",
    "applicationId": 27,
    "constructorId": 101,
    "startStateId": 74,
    "initiators": [
        "AFP"
    ],
    "properties": [
        {
            "id": 174,
            "name": "Estado",
            "description": "Estado del contrato",
            "displayName": "Estado",
            "type": {
                "id": 1,
                "name": "state",
                "applicationId": 0,
                "elementType": null,
                "elementTypeId": 0,
                "enumValues": null
            }
        },
        {
            "id": 175,
            "name": "Rutdeljubilado",
            "description": "Da a conocer el rut del jubilado a quien se le genero un certificado de saldo",
            "displayName": "Rut del jubilado",
            "type": {
                "id": 2,
                "name": "string",
                "applicationId": 0,
                "elementType": null,
                "elementTypeId": 0,
                "enumValues": null
            }
        },
        {
            "id": 176,
            "name": "Hashdeldocumento",
            "description": "Da a conocer el hash donde se encuentra el certificado de saldo",
            "displayName": "Hash del certificado de saldo",
            "type": {
                "id": 2,
                "name": "string",
                "applicationId": 0,
                "elementType": null,
                "elementTypeId": 0,
                "enumValues": null
            }
        },
        {
            "id": 177,
            "name": "Saldototal",
            "description": "El saldo total de jubilado, ingresado manualmente por su AFP",
            "displayName": "Saldo total",
            "type": {
                "id": 3,
                "name": "money",
                "applicationId": 0,
                "elementType": null,
                "elementTypeId": 0,
                "enumValues": null
            }
        },
        {
            "id": 178,
            "name": "OfferPrice",
            "description": "Posibles estados: 0",
            "displayName": "Estado del certificado",
            "type": {
                "id": 2,
                "name": "string",
                "applicationId": 0,
                "elementType": null,
                "elementTypeId": 0,
                "enumValues": null
            }
        }
    ],
    "constructor": {
        "id": 101,
        "name": "",
        "description": null,
        "displayName": "",
        "parameters": [
            {
                "id": 99,
                "name": "ingreserutdeljubilado",
                "description": "El rut del jubilado sin puntos ni guion",
                "displayName": "Ingrese rut del jubilado",
                "type": {
                    "id": 2,
                    "name": "string",
                    "applicationId": 0,
                    "elementType": null,
                    "elementTypeId": 0,
                    "enumValues": null
                }
            },
            {
                "id": 100,
                "name": "ingresesaldototaldeljubilado",
                "description": "El saldo total debe ser ingresado manualmente",
                "displayName": "Ingrese saldo total del jubilado",
                "type": {
                    "id": 3,
                    "name": "money",
                    "applicationId": 0,
                    "elementType": null,
                    "elementTypeId": 0,
                    "enumValues": null
                }
            },
            {
                "id": 101,
                "name": "ingreseelhashdeldocumento",
                "description": "El hash del documento donde se almacena el pdf del certificado de saldo",
                "displayName": "Ingrese el hash de donde se encuentra el certificado de saldo",
                "type": {
                    "id": 2,
                    "name": "string",
                    "applicationId": 0,
                    "elementType": null,
                    "elementTypeId": 0,
                    "enumValues": null
                }
            }
        ],
        "workflowId": 27
    },
    "functions": [
        {
            "id": 101,
            "name": "",
            "description": null,
            "displayName": "",
            "parameters": [
                {
                    "id": 99,
                    "name": "ingreserutdeljubilado",
                    "description": "El rut del jubilado sin puntos ni guion",
                    "displayName": "Ingrese rut del jubilado",
                    "type": {
                        "id": 2,
                        "name": "string",
                        "applicationId": 0,
                        "elementType": null,
                        "elementTypeId": 0,
                        "enumValues": null
                    }
                },
                {
                    "id": 100,
                    "name": "ingresesaldototaldeljubilado",
                    "description": "El saldo total debe ser ingresado manualmente",
                    "displayName": "Ingrese saldo total del jubilado",
                    "type": {
                        "id": 3,
                        "name": "money",
                        "applicationId": 0,
                        "elementType": null,
                        "elementTypeId": 0,
                        "enumValues": null
                    }
                },
                {
                    "id": 101,
                    "name": "ingreseelhashdeldocumento",
                    "description": "El hash del documento donde se almacena el pdf del certificado de saldo",
                    "displayName": "Ingrese el hash de donde se encuentra el certificado de saldo",
                    "type": {
                        "id": 2,
                        "name": "string",
                        "applicationId": 0,
                        "elementType": null,
                        "elementTypeId": 0,
                        "enumValues": null
                    }
                }
            ],
            "workflowId": 27
        }
    ],
    "startState": {
        "id": 74,
        "name": "CertificadoGenerado",
        "description": "The item is available",
        "displayName": "Certificado generado",
        "percentComplete": 100,
        "value": 0,
        "style": "Success",
        "workflowStateTransitions": []
    },
    "states": [
        {
            "id": 74,
            "name": "CertificadoGenerado",
            "description": "The item is available",
            "displayName": "Certificado generado",
            "percentComplete": 100,
            "value": 0,
            "style": "Success",
            "workflowStateTransitions": []
        }
    ]
} 

接下来,基于推论(由于执行发布的文档对于Node.js不够详细),使用axios执行POST,如下所示:

const request = await axios({
      method: "POST",
      url: `${WORKBENCH_API_URL}/api/v1/contracts?workflowId=27&contractCodeId=27&connectionId=1`,
      headers: { 'Authorization': `Bearer ${token.access_token}` },
      data: {
        workflowActionInput: {
          "workflowFunctionId": 101,
          "workflowFunctionParameters": [
            {
              "name": "ingreserutdeljubilado",
              "value": "1234567890",
              "workflowFunctionParameterId": 99
            },
            {
              "name": "ingresesaldototaldeljubilado",
              "value": "250000000",
              "workflowFunctionParameterId": 100
            },
            {
              "name": "ingreseelhashdeldocumento",
              "value": "FRfIYIfjTDFJHKYT",
              "workflowFunctionParameterId": 101
            }
          ]
        }
      }
    });

最后,响应日志显示:

{ Error: Request failed with status code 500
    at createError (/home/ubuntu/workspace/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/home/ubuntu/workspace/node_modules/axios/lib/core/settle.js:18:12)
    at IncomingMessage.handleStreamEnd (/home/ubuntu/workspace/node_modules/axios/lib/adapters/http.js:201:11)
    at IncomingMessage.emit (events.js:202:15)
    at endReadableNT (_stream_readable.js:1129:12)
    at processTicksAndRejections (internal/process/next_tick.js:76:17)
  config:
   { adapter: [Function: httpAdapter],
     transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     headers:
      { Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json;charset=utf-8',
        Authorization:
         'Bearer <token>',
        'User-Agent': 'axios/0.18.0',
        'Content-Length': 334 },
     method: 'post',
     url:
      '<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
     data:
      '{"workflowFunctionId":101,"workflowFunctionParameters":[{"name":"ingreserutdeljubilado","value":"1234567890","workflowFunctionParameterId":99},{"name":"ingresesaldototaldeljubilado","value":"250000000","workflowFunctionParameterId":100},{"name":"ingresehashdeldocumento","value":"FRfIYIfjTDFJHKYT","workflowFunctionParameterId":101}]}' },
  request:
   ClientRequest {
     _events:
      [Object: null prototype] {
        socket: [Function],
        abort: [Function],
        aborted: [Function],
        error: [Function],
        timeout: [Function],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 6,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     chunkedEncoding: false,
     shouldKeepAlive: false,
     useChunkedEncodingByDefault: true,
     sendDate: false,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: null,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: '<blockchain_App_url>',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: [TLSWrap],
        _parent: null,
        _host: '<blockchain_App_url>',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 25,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: '<blockchain_App_url>',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: [TLSWrap],
        _parent: null,
        _host: '<blockchain_App_url>',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 25,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object] },
     _header:
      'POST /api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1 HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: Bearer <token>\r\nUser-Agent: axios/0.18.0\r\nContent-Length: 334\r\nHost: <blockchain_App_url>\r\nConnection: close\r\n\r\n',
     _onPendingData: [Function: noopPendingOutput],
     agent:
      Agent {
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object],
        requests: {},
        sockets: [Object],
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        maxCachedSessions: 100,
        _sessionCache: [Object] },
     socketPath: undefined,
     timeout: undefined,
     method: 'POST',
     path:
      '/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
     _ended: true,
     res:
      IncomingMessage {
        _readableState: [ReadableState],
        readable: false,
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        socket: [TLSSocket],
        connection: [TLSSocket],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Array],
        trailers: {},
        rawTrailers: [],
        aborted: false,
        upgrade: false,
        url: '',
        method: null,
        statusCode: 500,
        statusMessage: 'Internal Server Error',
        client: [TLSSocket],
        _consuming: true,
        _dumped: false,
        req: [Circular],
        responseUrl:
         '<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
        redirects: [] },
     aborted: false,
     timeoutCb: null,
     upgradeOrConnect: false,
     parser: null,
     maxHeadersCount: null,
     _redirectable:
      Writable {
        _writableState: [WritableState],
        writable: true,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _options: [Object],
        _ended: true,
        _ending: true,
        _redirectCount: 0,
        _redirects: [],
        _requestBodyLength: 334,
        _requestBodyBuffers: [],
        _onNativeResponse: [Function],
        _currentRequest: [Circular],
        _currentUrl:
         '<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1' },
     [Symbol(isCorked)]: false,
     [Symbol(outHeadersKey)]:
      [Object: null prototype] {
        accept: [Array],
        'content-type': [Array],
        authorization: [Array],
        'user-agent': [Array],
        'content-length': [Array],
        host: [Array] } },
  response:
   { status: 500,
     statusText: 'Internal Server Error',
     headers:
      { 'transfer-encoding': 'chunked',
        'content-type': 'application/json',
        server: 'Kestrel',
        'request-context': 'appId=cid-v1:db0d0b41-4c65-4302-8151-77d69bdb0b7b',
        'x-correlation-id': '56831aa5-6ba1-42a2-9e19-16069f525716',
        'set-cookie': [Array],
        date: 'Thu, 14 Feb 2019 13:17:31 GMT',
        connection: 'close' },
     config:
      { adapter: [Function: httpAdapter],
        transformRequest: [Object],
        transformResponse: [Object],
        timeout: 0,
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        validateStatus: [Function: validateStatus],
        headers: [Object],
        method: 'post',
        url:
         '<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
        data:
         '{"workflowFunctionId":101,"workflowFunctionParameters":[{"name":"ingreserutdeljubilado","value":"1234567890","workflowFunctionParameterId":99},{"name":"ingresesaldototaldeljubilado","value":"250000000","workflowFunctionParameterId":100},{"name":"ingresehashdeldocumento","value":"FRfIYIfjTDFJHKYT","workflowFunctionParameterId":101}]}' },
     request:
      ClientRequest {
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header:
         'POST /api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1 HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: Bearer <token>\r\nUser-Agent: axios/0.18.0\r\nContent-Length: 334\r\nHost: scompblockchain1-6jii2u-api.azurewebsites.net\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path:
         '/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
        _ended: true,
        res: [IncomingMessage],
        aborted: false,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        _redirectable: [Writable],
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     data: { error: 'Internal Server Error' } } }

很抱歉,如果内容太长,请确保提供所有细节。这是api问题,代码语法问题还是天蓝色问题?

PD:天青石上的所有渗透都已被授予文档依据。

1 个答案:

答案 0 :(得分:0)

遇到类似问题。就我而言,问题出在令牌上。重新创建令牌(不仅调用API,还创建新的API以获取承载令牌)或您使用的任何方法。