How to Autowire a Service class in a custom connector in spring boot?

I am trying to create a custom out-bound connector which is going to call a third-party API.

The business logic to call the API is written in a service class. I am trying to autowire the service class to the connector class but its always coming as null, the Autowiring is not working.

I have also tried reading some configurations from application.properties using the @Value annotation it was not sucessful as well.

Can someone please help me in the same I am using camunda 8.

@Component
@OutboundConnector(
        name = "custom-email-connector",
        inputVariables = {"emailTo", "templateId", "body"},
        type = "email-connector")
public class NotificationConnector implements OutboundConnectorFunction {

    @Autowired
    private EmailService emailService;

    private static final Logger LOGGER = LoggerFactory.getLogger(NotificationConnector.class);

    @Override
    public Object execute(OutboundConnectorContext context) throws IOException, InterruptedException {
        LOGGER.info("variables {}",context.getJobContext().getVariables());
        final var connectorRequest = context.bindVariables(MyConnectorRequest.class);
        return executeConnector(connectorRequest);
    }

    private MyConnectorResult executeConnector(final MyConnectorRequest connectorRequest) throws IOException, InterruptedException {
        // TODO: implement connector logic

        return emailService.send(new EmailRequest(connectorRequest));

    }
}

Hello @shubham.parmar ,

to make that working, you should remove the service discovery from the class (the file located in META-INF/services) as the connector-runtime-spring has a bean discovery strategy implemented.

Also, I would advise you to use constructor injection to prevent this kind of misconfiguration.

Best regards,
Jonathan

When I remove the file from META-INF/services the connector stopped receiving any hit from the SAAS platform.

Hello @shubham.parmar ,

did you ensure that the connector is picked up as a bean?

Best regards,
Jonathan

@jonathan.lukas
Not sure on how to do that, can you please help me with that.

Hello @shubham.parmar ,

a simple way would to create a debug point on the constructor as you are now using constructor injection :wink:

Best regards,
Jonathan

@jonathan.lukas At the debug point during Start up it has the object but once the connector is triggered it becomes null

Hello @shubham.parmar ,

and the EmailService is injected via the constructor while the field is final?

private final EmailService emailService;

public NotificationConnector(EmailService emailService) {
  this.emailService = emailService;
}

Best regards,
Jonathan

Thanks @jonathan.lukas it really helped autowiring is working for me now, but I am still facing issues in reading configuration properties from application properties file.

@jonathan.lukas My autowiring is working with the solution you shared by removing the file from META_INF.services folder, but its only working on local runtime when I try to run it with dockerized run time the connector is not getting any hit.

Hello @shubham.parmar ,

how do you build your dockerized runtime?

Jonathan

@jonathan.lukas I have created my docker file over the camunda/connectors:8.5.0 docker image, please refer below docker file.

FROM camunda/connectors:8.5.0
ENV ZEEBE_CLIENT_SECURITY_PLAINTEXT=false \
    ZEEBE_CLIENT_CLOUD_CLUSTER-ID= \
    ZEEBE_CLIENT_CLOUD_CLIENT-ID=\
    ZEEBE_CLIENT_CLOUD_CLIENT-SECRET= \
    ZEEBE_CLIENT_CLOUD_REGION=ont-1 \
    CAMUNDA_OPERATE_CLIENT_URL=''
COPY target/email-notification-connector-0.1.0-SNAPSHOT.jar /opt/app/connector.jar
EXPOSE 8080
CMD ["java", "-jar", "/opt/app/connector.jar"]

Hello @shubham.parmar ,

this looks like you are placing your executable jar file and execute it directly.

If you run target/email-notification-connector-0.1.0-SNAPSHOT.jar on your machine, would it work?

Best regards,

Jonathan

@jonathan.lukas it works if I put the META_INF/services file but in that case autowiring stops working…If I remove the folder everything works as expected in local but the connector stops getting hits in docker

Hello @shubham.parmar ,

this is very interesting.

So local works, but moving the same jar to a docker image makes it not work…

Does the log of the docker container indicate any issue?

Best regards,

Jonathan

@jonathan.lukas NO, nothing happens after start up.

Hello @shubham.parmar ,

so they look the same as when you are running local?

could you please send the logs?

Best regards,

Jonathan

@jonathan.lukas Can we have a working session?

The spring boot application in the docker image is not aware of your component/bean when starting up as it uses the default packages for component scanning. Hence the auto-wiring is not working. When runnning using the local runtime it seems like its picked up as its part of the component scan path. More info: https://www.baeldung.com/spring-component-scanning

@shubham.parmar In your case you might want to have more control. I would recommend to look at the spring-boot-starter-camunda-connectors package that allows you to add the Connectors runtime to a spring boot application. This gives you full control over the application and its configuration and would allow you to use the @ComponentScan annotation as well.

1 Like