You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by GitBox <gi...@apache.org> on 2020/04/23 19:43:28 UTC

[GitHub] [pulsar] qmnonic opened a new issue #6809: Unable to create/register functions via REST API

qmnonic opened a new issue #6809:
URL: https://github.com/apache/pulsar/issues/6809


   **Describe the bug**
   Seems there was a change in the https://pulsar.apache.org/admin/v3/functions/{tenant}/{namespace}/{functionName} function, where the method signature changed, specifically the functionConfig parameter, which switched from a String (in 2.4.0) to an object (2.5.1) in FunctionsApiV3Resource.java as shown below in 2.5.1:
   
    ```
      @POST
       @Path("/{tenant}/{namespace}/{functionName}")
       @Consumes(MediaType.MULTIPART_FORM_DATA)
       public void registerFunction(final @PathParam("tenant") String tenant,
                                    final @PathParam("namespace") String namespace,
                                    final @PathParam("functionName") String functionName,
                                    final @FormDataParam("data") InputStream uploadedInputStream,
                                    final @FormDataParam("data") FormDataContentDisposition fileDetail,
                                    final @FormDataParam("url") String functionPkgUrl,
                                    final @FormDataParam("functionConfig") FunctionConfig functionConfig) {
   ```
   
   POSTs that worked before now return `400, Bad Request, b'{"reason":"Function config is not provided"}'`
   The result of this is it's seemingly impossible to register a function via the REST API (from python).  Perhaps I'm missing something?
   
   **To Reproduce**
   Steps to reproduce the behavior:
   2 different approaches, neither seem to work?  Both return 
   
   ```
       api_url = f"{API_URL_BASE}/v3/functions/{tenant}/{namespace}/{name}"
       files = {
           'url': 'file://pulsar/lib/org.apache.pulsar-pulsar-functions-api-examples-2.5.1.jar',
           'functionConfig': json.dumps({ 'tenant': 'example'})
        response = requests.post(api_url, files=files)
   ```
   
   error: 400, Bad Request, b'{"reason":"Function config is not provided"}'
   
   ```
   mp_encoder = MultipartEncoder(
           fields={
               'url': 'file://pulsar/lib/org.apache.pulsar-pulsar-functions-api-examples-2.5.1.jar',
               'functionConfig': json.dumps({ 'tenant': 'example'}),
           }
       )
       headers = {'Content-Type': mp_encoder.content_type}
        response = requests.post(api_url, data=mp_encoder, headers=headers)
   ```
   
   error: 400, Bad Request, b'{"reason":"Function config is not provided"}' 
   
   
   **Expected behavior**
   Expect an HTTP 200 and to see the function register.
   
   **Desktop (please complete the following information):**
    - OS: osx posting to linux running pulsar within the pulsar-all docker container
   
   **Additional context**
   Add any other context about the problem here.
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [pulsar] cdbartholomew commented on issue #6809: Unable to create/register functions via REST API

Posted by GitBox <gi...@apache.org>.
cdbartholomew commented on issue #6809:
URL: https://github.com/apache/pulsar/issues/6809#issuecomment-618693846


   @qmnonic I am not sure if this is helpful, but I am able to upload functions via the REST API in versions 2.4.2 to 2.5.1 using this JavaScript code:
   
   ```
   createFunction (cluster, functionPath, functionConfig, fileBlob, fileName) {
       let formData = new FormData()
       // Convert the functionConfig object to JSON then store it in a blob
       var blob = new Blob([JSON.stringify(functionConfig)], { type: 'application/json' })
       formData.append('functionConfig', blob)
       formData.append('data', fileBlob, fileName)
   
       const response = ApiBase().post(`${cluster}/functions/${functionPath}`, formData, {
         headers: {
           'Content-Type': 'multipart/form-data'
         }
       })
       return response
     },
   ```
   Sorry, but I have no idea how to translate this to Python.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [pulsar] qmnonic commented on issue #6809: Unable to create/register functions via REST API

Posted by GitBox <gi...@apache.org>.
qmnonic commented on issue #6809:
URL: https://github.com/apache/pulsar/issues/6809#issuecomment-618992822


    @sijie solution works. thanks!
   
   Thanks @cdbartholomew for the example !


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [pulsar] sijie commented on issue #6809: Unable to create/register functions via REST API

Posted by GitBox <gi...@apache.org>.
sijie commented on issue #6809:
URL: https://github.com/apache/pulsar/issues/6809#issuecomment-618703430


   @qmnonic 
   
   The `v2` endpoint still takes a serialized json string of FunctionConfig:  `/admin/v3/functions/{tenant}/{namespace}/{functionName} `
   
   There was a change in 2.5.0/2.4.1 - changing `v3` endpoint was changed to be a more structured way for uploading a FunctionConfig. 
   
   What you basically need to add in the post payload is to make sure the `functionConfig` is a JSON  payload in the form data.
   
   I think what you can do in python:
   
   ```
   mp_encoder = MultipartEncoder(
           fields={
               'url': 'file://pulsar/lib/org.apache.pulsar-pulsar-functions-api-examples-2.5.1.jar',
               'functionConfig': (None, json.dumps({ 'tenant': 'example'}), 'application/json')
           }
       )
       headers = {'Content-Type': mp_encoder.content_type}
        response = requests.post(api_url, data=mp_encoder, headers=headers)
   ```


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org