1
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?

Vova Bilyachat
  • 18,765
  • 4
  • 55
  • 80

1 Answers1

1

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

Vova Bilyachat
  • 18,765
  • 4
  • 55
  • 80
  • thanks Vova! agreed. that's one of the option. let me try and get back. – Tarunkumar Aghara Aug 23 '21 at 06:15
  • @TarunkumarAghara How it goes ?:) – Vova Bilyachat Aug 24 '21 at 00:05
  • thanks @Vova.. Tried just now . yes using DTO works ok... did not get chance to check `I thin with Tuple are allowed only if you want to pass multiple Fluxs in doc` --- will try it later and confirm back – Tarunkumar Aghara Aug 24 '21 at 10:27
  • I submitted one more question related to azure function at: https://stackoverflow.com/questions/68863759/azure-spring-boot-function-how-to-send-multiple-outputbinding-to-handleoutput I would really appreciate if you can take a look and suggest when you find sometime... @Vova – Tarunkumar Aghara Aug 24 '21 at 10:30
  • I tried with `public class HelloTupleHandler extends FunctionInvoker, Flux>, Tuple2, Flux>> {` but it didnt work - throws At the moment only Tuple-based function are supporting multiple arguments exception – Tarunkumar Aghara Aug 24 '21 at 12:33