0

I was spring cloud function in my project. We were using spring boot version 2.6.6 and spring-cloud-function-context version 3.2.3 along with other required dependency.In that I was using RoutingFunction (org.springframework.cloud.function.context.config) for the custom routing. I haven't created any bean for RoutingFunction and it was working fine.

@Component
@Slf4j
public class FxRouter<T> implements UnaryOperator<Message<T>> {

  private RoutingFunction routingFunction;

  @Autowired
  public FxRouter(RoutingFunction routingFunction) {
    this.routingFunction = routingFunction;
  }

  @Override
  public Message<T> apply(Message<T> object) {
    log.debug("In FxRouter, received object : {}", object);
    String springCloudFunctions = System.getenv(Constants.SPRING_CLOUD_FUNCTION_ORDER);
    log.debug("Execution sequence order : {}", springCloudFunctions);
    if (DMUtil.isNotBlank(springCloudFunctions)) {
      return startRouting(object,springCloudFunctions);
    } else {
      log.error("No Spring Cloud Function Order Property provided in Environment variable");
      return null;
    }
  }
    private Message<T> startRouting(Message<T> object,String springCloudFunctions) {
    log.debug("In FxRouter-startRouting, received object for routing : {}", object);
    T incomingAWSEvent = object.getPayload();
    List<String> functions =
      Arrays.asList(springCloudFunctions.split(Pattern.quote(Constants.FUNCTION_PIPE)));
    Iterator<String> functionsItr = functions.iterator();
    while (functionsItr.hasNext()) {
      String function = functionsItr.next();
      try {
        Message<T> functionMessage = MessageBuilder
          .withPayload(object.getPayload())
          .setHeader(Constants.SPRING_CLOUD_FUNCTION_DEFINITION, function)
          .setHeader(MessageHeaders.CONTENT_TYPE, Constants.CONTENT_TYPE_TEXT_PLAIN)
          .copyHeadersIfAbsent(object.getHeaders())
          .build();
        log.debug("Routing to function: {} ", function);
        Object payload = routingFunction.apply(functionMessage);
        object = getPayloadMessage(object, payload);
        if (!functionsItr.hasNext()) {
          return object;
        }
      } catch (CustomRuntimeException e) {
        Message<CustomRuntimeException> errorMessage = MessageBuilder
          .withPayload(e)
          .setHeader(Constants.SPRING_CLOUD_FUNCTION_DEFINITION, Constants.LOGGER_FUNCTION)
          .build();
        Message<T> message = routeToErrorHandlerOrReturnResponse(incomingAWSEvent, e, errorMessage);
        if (message != null) {
          return message;
        }
        break;
      }
    }
    return null;
  }

Recently I have updated spring boot version to 3.1.2 and using below spring cloud dependency version

<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2022.0.4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-adapter-aws</artifactId>
        </dependency>

Now after updating to the latest version. I am not able to autowire the RoutingFunction because it is saying Could not autowire. No beans of 'RoutingFunction' type found. So I try by creating the bean for RoutingFunction as below.

@Configuration(proxyBeanMethods = false)
public class RouterConfig {

  @Bean
  public RoutingFunction routingFunction() {
    return new RoutingFunction(null,null);
  }
}

But then I am getting error at runtime

 "stackTrace": "java.lang.NullPointerException\n\tat org.springframework.cloud.function.context.config.RoutingFunction.resolveFunction(RoutingFunction.java:237)\n\tat org.springframework.cloud.function.context.config.RoutingFunction.functionFromDefinition(RoutingFunction.java:206)\n\tat org.springframework.cloud.function.context.config.RoutingFunction.route(RoutingFunction.java:137)\n\tat org.springframework.cloud.function.context.config.RoutingFunction.apply(RoutingFunction.java:107)\n\tat 

Could any help me how to create bean for RoutingFunction

  • I can't tell you why, but can you add `debug=true` and see what the auto config report says? – spencergibb Aug 11 '23 at 14:29
  • Actually, I am not sure either, but I have just tried it with the versions that you have specified and everything works as expected and the default `RoutingFunction` is get wired properly. Please push a sample project that reproduces the issue somewhere on GitHub so we can tale a look – Oleg Zhurakousky Aug 14 '23 at 07:15
  • As for the NPE when creating your own instance of RF, what did you expect to happen when you execute `new RoutingFunction(null,null);`? – Oleg Zhurakousky Aug 14 '23 at 07:21
  • Hi @OlegZhurakousky, Kindly find link to sample project in which the issue could be seen in MyRouter class where while injecting bean for RoutingFunction through constructor autowiring (Could not autowire. No beans of 'RoutingFunction' type found. ) https://github.com/Mohit-Sardiwal/RoutingFunctionBean Appreciate your valuable feedback – Mohit Sardiwal Aug 14 '23 at 13:49
  • Just cloned and tested your project and it works as expected. I simply ran the provided `DemoApplication` class. I can see `RoutingFunction` being injected successfully. – Oleg Zhurakousky Aug 14 '23 at 15:00
  • First, I have no idea what does `spring.cloud.function.order="uppercase|lowercase”` means. Where did you get that from? We don't provide `order` property. Second, I am not sure why you are creating custom router if you are planning to route based on the property I am also not sure what is `fxAPIGWHandler` when your function definition is `apiGatewayHandler` Basically you have a number of errors/questions. Consider starting from the AWS Routing sample that we provide - https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-aws-routing – Oleg Zhurakousky Aug 16 '23 at 09:19

0 Answers0