Rafael Barioni
Rafael Barioni

Reputation: 193

AWS lambda + spring boot = not wiring component

I´m trying to use spring-boot inside my AWS lambda application to make calls to a SOAP web-service. But looks like it isn´t autowiring my SOAP component. Here´s my code:

@SpringBootApplication(scanBasePackages={"com.fenix"})
@EnableAutoConfiguration
@ComponentScan
public class Aplicacao extends SpringBootServletInitializer {

public static void main(String[] args) {
    SpringApplication.run(Aplicacao.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
    return springApplicationBuilder.sources(Aplicacao.class);
}
}

@Configuration
public class Beans {

@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan("com.tranzaxis.schemas", "org.radixware.schemas", "org.xmlsoap.schemas", "com.compassplus.schemas");
    return marshaller;
}

@Bean
public TranClient tranClient(Jaxb2Marshaller marshaller) {
    TranClient client = new TranClient();
    client.setDefaultUri("http://rhel72.tx:12301?wsdl");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    return client;
}

@Bean(name = "Tran")
public TranClient getTranClient() {
    return tranClient(marshaller());
}
}



public class PostMovimentacao extends Handler implements Service {

@Autowired
@Qualifier("Tran")
private TranClient tranClient;

@Inject
private PessoaCompassBO pessoaCompassBO;

private CompassConfig compassConfig;

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

@Override
protected ResponseEntity execute(ApiRequest request, Context context) throws HttpException {
    MovimentacaoRequest movimentacaoRequest = new MovimentacaoRequest();
    movimentacaoRequest.setOrigem(669L);
    movimentacaoRequest.setDestino(657L);
    movimentacaoRequest.setValor(BigDecimal.valueOf(1L));

    TranInvoke invoke = tranClient.movimentacaoFinanceira(movimentacaoRequest, compassConfig);  -->NullPointer here
    return ResponseEntity.of(Optional.of(invoke), Optional.empty(), HttpStatus.SC_OK);
}

@Override
public void setup() {
    try {
        compassConfig = CompassConfig.build();
    } catch (InvalidConfigException e) {
        LOGGER.error("Compass config error", e);
    }
}
}

Here´s my pom.xml:

    <build>
    <finalName>integrador-compass</finalName>
     <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.6.RELEASE</version>
                <configuration>
                    <layout>MODULE</layout>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.pitest</groupId>
            <artifactId>pitest-maven</artifactId>
            <version>1.1.11</version>
            <configuration>
                <targetClasses>
                    <param>com.fenix.*</param>
                </targetClasses>
                <excludedClasses>
                    <excludedClasse>com.fenix.handler.request*</excludedClasse>
                    <excludedClasse>com.fenix.handler.response*</excludedClasse>
                    <excludedClasse>com.fenix.model*</excludedClasse>
                </excludedClasses>
                <avoidCallsTo>
                    <avoidCallsTo>java.util.logging</avoidCallsTo>
                    <avoidCallsTo>org.apache.log4j</avoidCallsTo>
                    <avoidCallsTo>org.slf4j</avoidCallsTo>
                    <avoidCallsTo>org.apache.commons.logging</avoidCallsTo>
                </avoidCallsTo>
                <timestampedReports>false</timestampedReports>
                <outputFormats>
                    <outputFormat>XML</outputFormat>
                    <outputFormat>HTML</outputFormat>
                </outputFormats>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.16</version>
            <configuration>
                <includes>
                    <include>**/*Tests.java</include>
                    <include>**/*Test.java</include>
                </includes>
            </configuration>
        </plugin>
    </plugins>

    <extensions>
        <extension>
            <groupId>org.springframework.build</groupId>
            <artifactId>aws-maven</artifactId>
            <version>5.0.0.RELEASE</version>
        </extension>
    </extensions>
</build>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.0.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
    </dependency>

    <dependency>
        <groupId>com.fenix</groupId>
        <artifactId>compass-api</artifactId>
        <version>0.0.15</version>
    </dependency>
    <dependency>
        <groupId>com.fenix</groupId>
        <artifactId>lambda-commons</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.5.1</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.mashape.unirest</groupId>
        <artifactId>unirest-java</artifactId>
        <version>1.4.9</version>
    </dependency>
</dependencies>

Has anyone already used this configuration? I added spring-boot cause it was the only way to make my SOAP calls. If I try to make call just using code from WSDL, when it tries to connect to server, I got an error saying that request was empty. With spring-boot it doesn´t need to connect first, it just sends the request and it works fine.

Any help is welcome.

Thanks a lot.

Upvotes: 1

Views: 2816

Answers (1)

Tom Melo
Tom Melo

Reputation: 1499

Apparently, the Spring Boot application context is not being initialized in your code...If you really want to use Spring Boot in your Lambda Function you could try something like:

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-core</artifactId>
        <version>1.11.181</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-lambda</artifactId>
        <version>1.11.181</version>
    </dependency>
</dependencies>

Service Example:

@Component
public class MyService {

    public void doSomething() {
        System.out.println("Service is doing something");
    }

}

Some Bean Example:

@Component
public class MyBean {

    @Autowired
    private MyService service;

    public void executeService() {
       service.doSomething();
    }

}

A Lambda Handler Example:

@SpringBootApplication
public class LambdaHandler implements RequestHandler<Request, Response> {

    private ApplicationContext getApplicationContext(String [] args) {
        return new SpringApplicationBuilder(LambdaHandler.class)
                .web(false)
                .run(args);
    }

    public Response handleRequest(Request input, Context context) {
        ApplicationContext ctx = getApplicationContext(new String[]{});
        MyBean bean = ctx.getBean(MyBean.class);

        bean.executeService();

        return new Response();
    }
}

Upvotes: 1

Related Questions