0
votes

I'm maintaining a VSTS/TFS extension with a couple of build tasks and a custom service endpoint type with some dataSources. I need one of inputs in the build tasks to be a pickList populated with info coming from one of the dataSources defined in the service endpoint.

Here is my endpoint/dataSources definition in the extension manifest:

{
"id": "kiuwan-service-endpoint",
"description": "Kiuwan servide endpoint to connect to the Kiuwan platform",
"type": "ms.vss-endpoint.service-endpoint-type",
"targets": [
    "ms.vss-endpoint.endpoint-types"
],
"properties": {
    "name": "kiuwan",
    "displayName": "Kiuwan Platform",
    "url": {
        "displayName": "Kiuwan URL",
        "value": "https://api.kiuwan.com",
        "helpMarkDown": "The Kiuwan Service Endpoint URL is always https://api.kiuwan.com"
    },
    "dataSources": [
        {
            "name": "TestConnection",
            "endpointUrl": "{{endpoint.url}}/info",
            "resultSelector": "jsonpath:$.username"
        },
        {
            "name": "ListApplications",
            "endpointUrl": "{{endpoint.url}}/apps/list",
            "resultSelector": "jsonpath:$.[*].name"
        }
    ],
    "authenticationSchemes": [
        {
            "type": "ms.vss-endpoint.endpoint-auth-scheme-basic",
            "inputDescriptors": [
                {
                    "id": "username",
                    "name": "Username",
                    "description": "This is your Kiuwan username",
                    "inputMode": "textbox",
                    "isConfidential": false,
                    "validation": {
                        "isrequired": true,
                        "dataType": "string"
                    }
                },
                {
                    "id": "password",
                    "name": "Password",
                    "description": "Yup! this is your Kiuwan password",
                    "inputMode": "passwordBox",
                    "isConfidential": true,
                    "validation": {
                        "isrequired": true,
                        "dataType": "string"
                    }
                }
            ]
        }
    ],
    "helpMarkdown": "<a href=\"https://www.kiuwam.com\" target=\"_blank\"><b>Learn More</b></a>"
    }
}

This are the relevant task input definitions and the associated dataSourceBinding in the task.json file:

"inputs": [
{
    "name": "kiuwanConnection",
    "type": "connectedService:Kiuwan",
    "label": "Kiuwan Service",
    "defaultValue": "",
    "required": true,
    "helpMarkDown": "Kiuwan service connection"
},
{
    "name": "kiuwanappname",
    "type": "pickList",
    "label": "Available Kiuwan applications",
    "required": false,
    "visibleRule": "projectnameselector = kiuwanapp",
    "helpMarkDown": "Select an existing application in Kiuwan to associate results to."
}
],
"dataSourceBindings": [
    {
        "target": "kiuwanappname",
        "endpointId": "$(kiuwanConnection)",
        "dataSourceName": "ListApplications",
        "resultTemplate": "{{#.}}{\"Value\": \"{{.}}\",\"DisplayValue\": \"{{.}}\"},{{/.}}"
    }
]

After installing the extension on my local TFS 2017 for testing, I see the custom service type available in the New service endpoint pulldown. I define a new one for my project setting the right credentials. The connection is verified using the TestConnection dataSource I defined.

However, when I go to see one of my build tasks the pick list that should be filled with the response from the dataSource ListApplication, it is empty.

It seems that the issue may be the moustche template I defined in the dataSourceBinding. This is what I should be getting from the REST call in the dataSource:

[
   "A Customer Portal",
   "A Fine PHP Application",
   "A Simple Chess Game"
]

After the jsonpath is applied. Running mustache from the command line with the template defined in the dataSourceBinding, I get this (in this case I didn't escaped the "):

{"Value": "A Customer Portal","DisplayValue": "A Customer Portal"},{"Value": "A Fine PHP Application","DisplayValue": "A Fine PHP Application"},{"Value": "A Simple Chess Game","DisplayValue": "A Simple Chess Game"},

Which is what I expect.

Any ideas why this may not be working? Is there a way to debug this? Any way to know if the call is being made to my service endpoint? Besides possible typos in the typos in the task and extension manifest json files, there may be different points of failure here (the REST call the jsonpath, the mustache template... and I'm blind.

Any help you can provide is highly appreciated. best, J.

1

1 Answers

1
votes

First, if apps/list API returns array object (e.g. [{"name":"n1"},{"name":"n2"}]), then replace jsonpath:$.[*].name to jsonpath:$[*].name.

Secondly, the REST API returns an array, you can remove resultTemplate definition from dataSourceBindings:

"dataSourceBindings": [
    {
        "target": "kiuwanappname",
        "endpointId": "$(kiuwanConnection)",
        "dataSourceName": "ListApplications"
    }
]

On the other hand, there isn't the way to debug it, just can capture the request when click the dropdownlist control.