Azure-Samples / blockchain

Azure Blockchain Content and Samples
MIT License
823 stars 687 forks source link

Create contract in azure blockchain workbench using the api and Node.js #146

Closed yieniggu closed 5 years ago

yieniggu commented 5 years ago

Please provide us with the following information:

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [ x] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

I'm trying to create a new contract instance using the workbench api, from Node.js using axios package:

First I created the service principal, as the docs request, for getting the bearer token and access the api resources.

Then, perform a GET request to /api/v1/applications/workflows/ and get the following results:

{
    "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": []
        }
    ]
} 

Any log messages given by the failure

Next, based on inference (since the documentation to perform a post isn't detailed enough for Node.js) perform a POST using axios as follows:

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
            }
          ]
        }
      }
    });

Finally, the log of the response shows:

{ 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' } } }

Additionaly, this is one of the logs of the application insights service in my blockchain workbench resources group, after it receives a POST request:

System.ArgumentNullException:
   at System.Linq.Enumerable.Select (System.Linq, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at Microsoft.AppBuilder.DataAccess.ContractActionParameterUDTT..ctor (data-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nulldata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /data-access/AppBuilderDatabaseHelpers/UserDefinedTables/ContractActionParameterUDTT.csdata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 27)
   at Microsoft.AppBuilder.DataAccess.ContractHelper+<>c__DisplayClass1_0+<<CreateContractAsync>b__0>d.MoveNext (data-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nulldata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /data-access/AppBuilderDatabaseHelpers/ContractHelper.csdata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 36)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.DataAccess.DapperConnectionService+<>c__DisplayClass6_0`1+<<ExecuteWithDapperConnectionAsync>b__0>d.MoveNext (data-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Polly.Policy+<>c__DisplayClass208_0`1+<<ExecuteAsyncInternal>b__0>d.MoveNext (Polly, Version=5.8.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Polly.RetrySyntaxAsync+<>c__DisplayClass21_1+<<WaitAndRetryAsync>b__1>d.MoveNext (Polly, Version=5.8.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Polly.Retry.RetryEngine+<ImplementationAsync>d__1`1.MoveNext (Polly, Version=5.8.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Polly.Retry.RetryEngine+<ImplementationAsync>d__1`1.MoveNext (Polly, Version=5.8.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Polly.Policy+<ExecuteAsyncInternal>d__208`1.MoveNext (Polly, Version=5.8.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.DataAccess.DapperConnectionService+<ExecuteWithDapperConnectionAsync>d__6`1.MoveNext (data-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.DataAccess.ContractHelper+<CreateContractAsync>d__1.MoveNext (data-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nulldata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /data-access/AppBuilderDatabaseHelpers/ContractHelper.csdata-access, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 30)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.API.Controllers.ContractsController+<ContractPost>d__3.MoveNext (Microsoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /appbuilder.api/Controllers/ContractsController.csMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 148)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__10.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeInnerFilterAsync>d__14.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext (Microsoft.AspNetCore.Routing, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware+<Invoke>d__7.MoveNext (Microsoft.AspNetCore.Cors, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.API.UserInfoMiddleware+<InvokeAsync>d__10.MoveNext (Microsoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /appbuilder.api/UserInfoMiddleware.csMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 89)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AppBuilder.API.AppBuilderErrorHandler+<Invoke>d__3.MoveNext (Microsoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: /appbuilder.api/AppBuilderErrorHandler.csMicrosoft.AppBuilder.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 34)

Apologize if the content of this is too long, just wanted to be sure to give every detail. Is this a problem with the api, the code syntax or an azure problem?

PD: All permisions on azure have been granted as the docs point.

yieniggu commented 5 years ago

UPDATE:

Changed to swagger library (still in Node.js). Thinking of a more compatible way to interact with the resource. This is the new portion of code:

var qs = require('qs');
const axios = require('axios');
const Swagger = require("swagger-client");

const AUTHORITY = 'https://login.microsoftonline.com/*';
const WORKBENCH_API_URL = 'https://scompblockchain1-6jii2u-api.azurewebsites.net';
const RESOURCE = '*';
const CLIENT_APP_Id = '*';
const CLIENT_SECRET = '*';

// Getting token from AAD
const acquireTokenWithClientCredentials = async(resource, clientId, clientSecret, authority) => {
  const requestBody = {
    resource: resource,
    client_id: clientId,
    client_secret: clientSecret,
    grant_type: 'client_credentials'
  };
  console.log(acquireTokenWithClientCredentials);

  const response = await axios({
    method: 'POST',
    url: `${authority}/oauth2/token`,
    data: qs.stringify(requestBody),
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
  });

  return response.data;
}

main = async() => {
  try {
    const token = await acquireTokenWithClientCredentials(RESOURCE, CLIENT_APP_Id, CLIENT_SECRET, AUTHORITY);

    const request = {
      url: `${WORKBENCH_API_URL}/api/v2/contracts?workflowId=1&contractCodeId=1&connectionId=1`,
      method: "POST",
      headers: { 'Content-Type': 'application/json;charset=utf-8;odata=verbose', 'Authorization': `Bearer ${token.access_token}`},
      body: {
        workflowActionInput: {
          workflowFunctionID: 1,
          workflowActionParameters: [{
              name: "description",
              value: "Quiero verder un auto",
              workflowFunctionParameterId: 2
            },
            {
              name: "price",
              value: "2500000",
              workflowFunctionParameterId: 3
            }
          ]
        }
      }
    }

    let res = await Swagger.http(request);

    /*const request = await axios({
      method: "POST",
      url: `${WORKBENCH_API_URL}/api/v2/contracts?workflowId=1&contractCodeId=1&connectionId=1`,
      headers: {'Authorization': `Bearer ${token.access_token}` },
      data: {
        workflowActionInput: {
          "workflowFunctionID": 1,
          "workflowActionParameters": [
            {
              "name": "description",
              "value": "Quiero verder un auto",
              "workflowFunctionParameterId": 2
            },
            {
              "name": "price",
              "value": "2500000",
              workflowFunctionParameterId: 3
            }
          ]
        }
      } 
    });*/

    //console.log("POST COMPLETADO (?: : ", res);
  }
  catch (err) {
    console.error(err);
  }
}

main();

And this is the actual error log:

{ Error: Bad Request at Function.<anonymous> (/home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/swagger-client/dist/index.js:1:8679) at tryCatch (/home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/regenerator-runtime/runtime.js:62:40) at Generator.invoke [as _invoke] (/home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/regenerator-runtime/runtime.js:296:22) at Generator.prototype.(anonymous function) [as next] (/home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/regenerator-runtime/runtime.js:114:21) at step (/home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30) at /home/ubuntu/workspace/Example/blockchain/blockchain-workbench/auth-samples/nodejs/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13 at processTicksAndRejections (internal/process/next_tick.js:81:5) status: 400, statusCode: 400, response: { ok: false, url: 'https://scompblockchain1-6jii2u-api.azurewebsites.net/api/v2/contracts?workflowId=1&contractCodeId=1&connectionId=1', status: 400, statusText: 'Bad Request', headers: { 'transfer-encoding': 'chunked', 'content-type': 'application/json; charset=utf-8', server: 'Kestrel', 'request-context': 'appId=cid-v1:db0d0b41-4c65-4302-8151-77d69bdb0b7b', 'x-correlation-id': '3bd77780-6a2d-4917-ab93-388bd5a9a262', 'set-cookie': 'ARRAffinity=57e591747cde1209152d99cdbdb64ff3aaf6a1963b12c10e97bbe6fa5a4a72d6;Path=/;HttpOnly;Domain=scompblockchain1-6jii2u-api.azurewebsites.net', date: 'Fri, 15 Feb 2019 13:37:05 GMT', connection: 'close' }, text: '"Must provide a valid workflow action input"', data: '"Must provide a valid workflow action input"', body: 'Must provide a valid workflow action input', obj: 'Must provide a valid workflow action input' } }

brendalee commented 5 years ago

Thanks for the detail. I'm not sure what exactly is going on, but I would double check the input that you're putting in based on your config/smart contract that you uploaded. The error messages near the bottom seem to indicate that your workflow action input may not match properly.

yieniggu commented 5 years ago

@brendalee thanks for your answer, i think it's just a schema or library error used in my Node.js backend. I hope you can help me solve this, since api is the final step of my poc.

You can found here that using postman (after imported the collection as pointed here works perfectly, but from my backend stills outputs that must provide a valid workflow action input.

andreatosato commented 5 years ago

ServicePrincipal Token don't work fine. With administrator bearer token, work fine. Why? @brendalee administrator bearer token is copy and past from Web Portal of workbenck. @yieniggu any news of this bug?

brendalee commented 5 years ago

If you're using a service principal for system to system integrations, we recommend use the messaging API, which will solve this issue. Let us know if you run into this problem again!

shobhit-kumar-code commented 5 years ago

Hi, @yieniggu how did you fix the issue? I am facing a the same issue on postman with the API ti create a contract?

shobhit-kumar-code commented 5 years ago

I found the same issue here as wel, any updates? https://social.msdn.microsoft.com/Forums/sqlserver/ja-JP/f7b04e01-bb7b-42ee-a1d7-0c125c1f52f9/error-in-createcontract-azure-blockchain-rest-api?forum=azureblockchain

Eeeva1227 commented 5 years ago

Hi, @yieniggu how did you fix the issue? I am facing a the same issue on postman with the API ti create a contract?

I have the same issue when post a new contract via postman by impersonating a user. when the post request is finished, there are no contract properties and ledgerIdentifier for this newly-created contract. Moreover, there is no available actions for this contract. What could possibly go wrong here? Or is this not a supported functionality right now? Below is the data I get for the newly created contract { "id": 12, "provisioningStatus": 0, "timestamp": "2019-08-15T18:41:49.5566667", "connectionID": 1, "ledgerIdentifier": null, "deployedByUserId": 1, "workflowId": 2, "requestId": "7140c8cd-8174-46af-8c1e-bb0717e02073", "contractCodeId": 2, "contractProperties": [], "transactions": [], "contractActions": [ { "id": 30, "userId": 1, "provisioningStatus": 0, "timestamp": "2019-08-15T18:41:49.5566667", "parameters": [ { "name": "description", "value": "from postman", "workflowFunctionParameterId": 9 }, { "name": "transferability", "value": "true", "workflowFunctionParameterId": 10 }, { "name": "expired time", "value": "1569011400", "workflowFunctionParameterId": 11 } ], "workflowFunctionId": 7, "transactionId": null, "workflowStateId": null, "requestId": "7140c8cd-8174-46af-8c1e-bb0717e02073", "eventId": null } ] }

amlestin commented 4 years ago

Make sure you are all using the correct parameter names in your JSON POST request. I was stuck for days but detailed information from this function helped me:

https://docs.microsoft.com/en-us/rest/api/azure-blockchain-workbench/applications/workflowget