Search code examples
javaspring-bootazureazure-functionsspring-cloud-function

Azure spring boot function-how to pass trigger and input binding both to handleRequest method at same time?


package com.att.trace.function;

import java.util.Optional;

import com.att.trace.function.model.User;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.BlobInput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import com.microsoft.azure.functions.annotation.StorageAccount;

import org.springframework.cloud.function.adapter.azure.FunctionInvoker;

import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

public class HelloHandler extends FunctionInvoker<Tuple2<User, String>, String> {

        @FunctionName("hello")
        @StorageAccount("AzureWebJobsStorage")
        public HttpResponseMessage execute(@HttpTrigger(name = "request", methods = { HttpMethod.GET,
                        HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<User>> request,
                        @BlobInput(name = "requestjsonblob", dataType = "string", path = "requestjson/{name}.json") String requestjson,
                        ExecutionContext context) {
                User user = request.getBody().get();
                System.out.println("requestjson=" + requestjson);
                Tuple2<User, String> input = Tuples.of(user, requestjson);
                handleRequest(input, context);
                return request.createResponseBuilder(HttpStatus.OK).body("ok")
                                .header("Content-Type", "application/json").build();
        }
}


package com.att.trace.function;

import java.util.function.Function;

import com.att.trace.function.model.User;

import org.springframework.stereotype.Component;

import reactor.util.function.Tuple2;

@Component
public class Hello implements Function<Tuple2<User, String>, String> {
  public String apply(Tuple2<User, String> objects) {
    System.out.println("objects.getT1()=" + objects.getT1());
    System.out.println("objects.getT2()=" + objects.getT2());
    String output = "test output";
    return output;

  }
}

getting below exception when I create tuple of Http trigger and blobinput and send it to handleRequest..

[2021-08-20T09:53:12.816Z] java.lang.UnsupportedOperationException: At the moment only Tuple-based function are supporting multiple arguments [2021-08-20T09:53:12.818Z] at

I need to send both inputs to handleRequest method... any clue how to achieve that?


Solution

  • Spent some time and the only way I could achieve that what you want is by using DTO class.

    package com.example.demo.model;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    @Data
    @AllArgsConstructor
    public class HelloInputArguments {
        private User user;
        private String content;
    }
    

    Then handler is easy

    package com.example.demo;
    
    
    import com.example.demo.model.HelloInputArguments;
    import com.example.demo.model.User;
    import com.microsoft.azure.functions.*;
    import com.microsoft.azure.functions.annotation.*;
    import org.springframework.cloud.function.adapter.azure.FunctionInvoker;
    
    import java.util.Optional;
    
    
    public class HelloHandler extends FunctionInvoker<HelloInputArguments, String> {
    
        @FunctionName("hello")
        @StorageAccount("DefaultConnection")
        public HttpResponseMessage execute(
                @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<User>> request,
                @BlobInput(name = "file", dataType = "string", path = "requestjson/proam.json") String content,
                ExecutionContext context) {
            User user = request.getBody().get();
    
            return request.createResponseBuilder(HttpStatus.OK)
                    .body(handleRequest(new HelloInputArguments(user, content), context))
                    .header("Content-Type", "application/json")
                    .build();
        }
    }
    

    And function

    package com.example.demo;
    
    import com.example.demo.model.HelloInputArguments;
    import org.springframework.stereotype.Component;
    
    import java.util.function.Function;
    
    @Component
    public class Hello implements Function<HelloInputArguments, String> {
        public String apply(HelloInputArguments input) {
          return input.getContent();
        }
    }
    

    I thin with Tuple are allowed only if you want to pass multiple Fluxs in doc