Integration test with Spring-context doesn't receive RabbitMQ messages - rabbitmq

RabbitMQ MessageConsumer doesn't receive the published message
I'm writing an integration test which should received a message from a queue and do the processing. But the consumer simply doesn't receive the message.
When I manually inject the dependencies - without Spring context, things works fine. But when I use SpringContext, the consumer doesn't receive the message.
The SpringInfraConfig.class loads values from environment variables. To 'emule' the the environment I'm usging the class EnvironmentVariables from this library. The env variables are loaded fine - checked running debug.
NOTE when I mention without SpringContext works fine, I wasn't using the Environment Library too.
To publish the message into RabbitMQ queue, I'm doing it 'manually' on test method. The message is published fine. I wrote a consming test code before call my real testing class. It's a simple raw consumer overriding DefaultConsumer#handleDelivery with a sysout to print the incoming message. Works.
When I test using my real testing class - MessageConsumerServiceImpl.class it just log starting consuming from queue and the test ends.
Something pretty weird occurs when I debug and step into all methods - the message is received and in the middle of processing it ends up without completing all calls - the test just stops, no error are threw too.
Another weird thing is - enabling the RabbitMQ management plugin, there are no queues, exchange, channels or even a connection open. I checked this in debug running while stoped into a break-point.
SpringConfig class
#Import({SpringCoreConfig.class})
#ComponentScan({"br.com.fulltime.fullarm.fullcam.integration.infra", "br.com.fulltime.fullarm.cross.cutting", "br.com.fulltime.fullarm.infrastructure.commons"})
#Configuration
public class SpringInfraConfig {
#Bean
public FInfraSettings getFInfraSettings() {
Map<String, String> fInfraMap = new HashMap<>();
fInfraMap.put("F_INFRA_RABBIT_HOST", "f_infra_rabbit_host");
fInfraMap.put("F_INFRA_EXCHANGE", "f_infra_exchange");
fInfraMap.put("F_INFRA_QUEUE", "f_infra_queue");
fInfraMap.put("F_INFRA_PROCESS_ID", "f_infra_process_id");
fInfraMap.put("F_INFRA_DESCRIPTION", "f_infra_description");
fInfraMap.put("F_INFRA_TEXT", "f_infra_text");
fInfraMap.put("F_INFRA_TAG", "f_infra_tag");
fInfraMap.put("F_INFRA_WARNING_TIME", "f_infra_warning_time");
fInfraMap.put("F_INFRA_CRITICAL_TIME", "f_infra_critical_time");
return new FInfraSettings(
getEnv("f_infra_run", "false").asBoolean(),
getEnv("f_infra_ka_time", "1").asInt(),
fInfraMap);
}
#Bean
public ApplicationSettings getApplicationSettings() {
return new ApplicationSettings(
getEnv("process_name", "FullArm-FullCam Integration").asString(),
getEnv("process_version", "DEFAULT-1.0.0").asString());
}
#Bean
public PushoverSettings getPushoverSettings() {
return new PushoverSettings(
getEnv("pushover_api", "invalido").asString(),
getEnv("pushover_user_id", "invalido").asString(),
getEnv("pushover_run", "false").asBoolean());
}
#Bean
public RabbitMQSettings getRabbitMQSettings() {
return new RabbitMQSettings(
new RabbitConnectionInfo(
getEnv("rabbitmq_host", "127.0.0.1").asString(),
getEnv("rabbitmq_port", "5672").asInt(),
getEnv("rabbitmq_virtual_host", "/").asString(),
getEnv("rabbitmq_username", "guest").asString(),
getEnv("rabbitmq_password", "guest").asString()),
new RabbitConnectionInfo(
getEnv("rabbitmq_fullcam_host", "127.0.0.1").asString(),
getEnv("rabbitmq_fullcam_port", "5672").asInt(),
getEnv("rabbitmq_fullcam_virtual_host", "/").asString(),
getEnv("rabbitmq_fullcam_username", "guest").asString(),
getEnv("rabbitmq_fullcam_password", "guest").asString()),
new RabbitQueueInfo(
getEnv("rabbitmq_consumer_fullarm_queue", "fcomQueConsumerFullCam").asString(),
getEnv("rabbitmq_consumer_fullarm_exc", "fcomExcConsumer").asString(),
getEnv("rabbitmq_consumer_fullarm_rk", "fcomRKConsumerFullCam").asString()),
new RabbitQueueInfo(
getEnv("rabbitmq_consumer_fullcam_queue", "foo").asString(),
getEnv("rabbitmq_consumer_fullcam_exc", "foo").asString(),
getEnv("rabbitmq_consumer_fullcam_rk", "foo").asString()),
new RabbitQueueInfo(
getEnv("rabbitmq_publish_fullcam_queue", "fullcamRequest").asString(),
getEnv("rabbitmq_publish_fullcam_exc", "fullcamRequestExc").asString(),
getEnv("rabbitmq_consumer_fullarm_rk", "fullcamRequestRK").asString()));
}
#Bean
public RedisSettings getRedisSettings() {
return new RedisSettings(
getEnv("redis_host", "localhost").asString(),
getEnv("redis_port", "6379").asInt(),
getEnv("redis_password", "123456").asString());
}
#Bean
public Connection getConnection() {
try {
return RabbitConnectionFactory.create(getRabbitMQSettings().getConnectionInfo());
} catch (IOException | TimeoutException e) {
throw new ShutdownException(e);
}
}
#Bean
public Logging getLogging() {
return new DefaultLogger();
}
MessageConsumerServiceImpl class
#Component
public class MessageConsumerServiceImpl implements MessageConsumerService {
private final Connection rabbitMQConnection;
private final MessageConsumerFactory consumerFactory;
private final RabbitMQSettings mqSettings;
private final ShutdownService shutdownService;
private final Logging logger;
#Inject
public MessageConsumerServiceImpl(Connection rabbitMQConnection,
MessageConsumerFactory consumerFactory,
RabbitMQSettings mqSettings,
ShutdownService shutdownService,
Logging logger) {
this.rabbitMQConnection = rabbitMQConnection;
this.consumerFactory = consumerFactory;
this.mqSettings = mqSettings;
this.shutdownService = shutdownService;
this.logger = logger;
}
#Override
public void startListening() {
try {
RabbitQueueInfo commandQueInfo = mqSettings.getRabbitMQFullArmConsumerQueue();
final String queue = commandQueInfo.getQueue();
Channel channel = rabbitMQConnection.createChannel();
channel.queueDeclare(queue, true, false, false, null);
MessageConsumer commandConsumer = consumerFactory.create(channel);
logger.info("[MESSAGE-CONSUMER] - Consumindo da fila: {}", queue);
channel.basicConsume(queue, commandConsumer);
} catch (IOException e) {
logger.error("[MESSAGE-CONSUMER] - ShutdownException", e);
shutdownService.shutdown(e);
}
}
Integration Test Class
public class MessageConsumerServiceImplIntegrationTest {
private static final Integer RABBITMQ_PORT = 5672;
private static final String RABBITMQ_EXC = "fcomExcConsumer";
private static final String RABBITMQ_QUEUE = "fcomQueFullcamIntegration";
private static final String RABBITMQ_RK = "fcomRKConsumerFullCam";
private static final String REDIS_PASSWORD = "123456";
private static final int REDIS_PORT = 6379;
public static RabbitMQContainer rabbitMqContainer;
public static GenericContainer redisContainer;
static {
redisContainer = new GenericContainer<>("redis:5.0.3-alpine")
.withExposedPorts(REDIS_PORT)
.withCommand("redis-server --requirepass " + REDIS_PASSWORD)
.waitingFor(Wait.forListeningPort());
redisContainer.start();
}
static {
rabbitMqContainer = new RabbitMQContainer()
.withExposedPorts(RABBITMQ_PORT)
.withExposedPorts(15672)
.withUser("guest", "guest")
.withVhost("/")
.waitingFor(Wait.forListeningPort());
rabbitMqContainer.start();
}
#Rule
public final EnvironmentVariables environmentVariables = new EnvironmentVariables()
.set("rabbitmq_host", rabbitMqContainer.getContainerIpAddress())
.set("rabbitmq_port", String.valueOf(rabbitMqContainer.getMappedPort(RABBITMQ_PORT)))
.set("rabbitmq_virtual_host", "/")
.set("rabbitmq_username", "guest")
.set("rabbitmq_password", "guest")
.set("rabbitmq_fullcam_host", rabbitMqContainer.getContainerIpAddress())
.set("rabbitmq_fullcam_port", String.valueOf(rabbitMqContainer.getMappedPort(RABBITMQ_PORT)))
.set("rabbitmq_fullcam_virtual_host", "/")
.set("rabbitmq_fullcam_username", "guest")
.set("rabbitmq_fullcam_password", "guest")
.set("rabbitmq_publish_fullcam_queue", "Fullarm.Request")
.set("rabbitmq_publish_fullcam_exc", "fcomExcFullcam")
.set("rabbitmq_publish_fullcam_rk", "fcomRKFullcamRequest")
.set("rabbitmq_consumer_fullarm_queue", RABBITMQ_QUEUE)
.set("rabbitmq_consumer_fullarm_exc", RABBITMQ_EXC)
.set("rabbitmq_consumer_fullarm_rk", RABBITMQ_RK)
.set("rabbitmq_consumer_fullcam_queue", "Fullarm.Reponse")
.set("rabbitmq_consumer_fullcam_exc", "fcomExcFullarm")
.set("rabbitmq_consumer_fullcam_rk", "fcomRKFullarmFullcamIntegration")
.set("f_infra_rabbit_host", "abobora")
.set("f_infra_exchange", "abobora")
.set("f_infra_queue", "abobora")
.set("f_infra_process_id", "0")
.set("f_infra_description", "abobora")
.set("f_infra_text", "abobora")
.set("f_infra_tag", "0")
.set("f_infra_warning_time", "0")
.set("f_infra_critical_time", "0")
.set("f_infra_run", "false")
.set("f_infra_ka_time", "1")
.set("redis_host", redisContainer.getContainerIpAddress())
.set("redis_port", String.valueOf(redisContainer.getMappedPort(REDIS_PORT)))
.set("redis_password", REDIS_PASSWORD);
private MessageConsumerService instance;
private ApplicationContext context;
#Before
public void setUp() {
context = new AnnotationConfigApplicationContext(SpringInfraConfig.class);
instance = context.getBean(MessageConsumerService.class);
}
#Test
public void deveProcessarRequisicao() throws IOException, TimeoutException {
String message = "{ \"tipoPacote\" : 3, \"descricao_painel\" : \"Casa Mauro Naves\", \"setor_disparado\" : \"Porta da Frente\", \"data_disparo\" : 1587151300000, \"cameras\" : [90851, 90853, 90854] }";
ConnectionFactory factory = new ConnectionFactory();
RabbitMQSettings settings = context.getBean(RabbitMQSettings.class);
factory.setHost(settings.getConnectionInfo().getHost());
factory.setPort(settings.getConnectionInfo().getPort());
factory.setVirtualHost(settings.getConnectionInfo().getVirtualHost());
factory.setAutomaticRecoveryEnabled(true);
factory.setUsername(settings.getConnectionInfo().getUsername());
factory.setPassword(settings.getConnectionInfo().getPassword());
factory.setRequestedHeartbeat(50);
Connection connection = factory.newConnection();
RabbitQueueInfo commandQueInfo = settings.getRabbitMQFullArmConsumerQueue();
Channel channel = connection.createChannel();
channel.exchangeDeclare(commandQueInfo.getExchange(), "direct", true);
channel.queueDeclare(commandQueInfo.getQueue(), true, false, false, null);
channel.queueBind(commandQueInfo.getQueue(), commandQueInfo.getExchange(), commandQueInfo.getRoutingKey());
channel.basicPublish(commandQueInfo.getExchange(), commandQueInfo.getRoutingKey(), MessageProperties.PERSISTENT_BASIC, message.getBytes());
channel.close();
connection.close();
instance.startListening();
}
Gradle depencies
core-build.gradle
dependencies {
compile group: 'javax.inject', name: 'javax.inject', version: '1'
compile group: 'org.springframework', name: 'spring-context', version: '5.2.5.RELEASE'
compile 'com.fasterxml.jackson.core:jackson-core:2.7.1'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.1-1'
compile group: 'br.com.fulltime.fullarm', name: 'cross-cutting-commons', version: '1.13.0'
compile group: 'br.com.fulltime.fullarm', name: 'constants', version: '1.110.0'
}
infra-build.gradle
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile "org.testcontainers:testcontainers:1.14.1"
testCompile "org.testcontainers:rabbitmq:1.14.1"
testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.19.0'
compile project(':core')
compile group: 'br.com.fulltime.fullarm', name: 'infrastructure-commons', version: '1.6.0'
compile group: 'br.com.fulltime.fullarm', name: 'FInfraJavaLibrary', version: '2.3.0'
compile group: 'br.com.fulltime.fullarm', name: 'pushover-lib', version: '1.0.0'
compile group: 'redis.clients', name: 'jedis', version: '3.3.0'
}
Test output
Testing started at 08:38 ...
Starting Gradle Daemon...
Gradle Daemon started in 815 ms
> Task :core:compileJava UP-TO-DATE
> Task :core:processResources NO-SOURCE
> Task :core:classes UP-TO-DATE
> Task :core:jar UP-TO-DATE
> Task :infra:compileJava UP-TO-DATE
> Task :infra:processResources NO-SOURCE
> Task :infra:classes UP-TO-DATE
> Task :infra:compileTestJava
> Task :infra:processTestResources NO-SOURCE
> Task :infra:testClasses
> Task :infra:test
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.junit.contrib.java.lang.system.EnvironmentVariables (file:/home/*omited*/.gradle/caches/modules-2/files-2.1/com.github.stefanbirkner/system-rules/1.19.0/d541c9a1cff0dda32e2436c74562e2e4aa6c88cd/system-rules-1.19.0.jar) to field java.util.Collections$UnmodifiableMap.m
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2020-05-14 08:38:35 INFO - [MESSAGE-CONSUMER] - Consumindo da fila: fcomQueFullcamIntegration
WARNING: Please consider reporting this to the maintainers of org.junit.contrib.java.lang.system.EnvironmentVariables
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 22s
5 actionable tasks: 2 executed, 3 up-to-date
08:38:36: Task execution finished ':infra:test --tests "br.com.fulltime.fullarm.fullcam.integration.infra.consumer.MessageConsumerServiceImplIntegrationTest.deveProcessarRequisicao"'.
I have no more idea about the problema. Any help is welcome.
Thanks in advance
UPDATE
I wrote my test again making it simplier. I wrote one code with Spring-context and env stuff and another one without Spring-context and env stuff. BOTH DIDN'T worked.
So, for testing porpuse I coded a simple Thread#sleep() and guess what, BOTH tests worked!
I think the cause is the RabbitMQ DefaultConsumer instanciate a new Thread for consuming messages, what releases the main testing Thread and it got stoped. Since main Thread has been stoped all others get stopped too.
So I think we got a synchronism test problem here.
It's possible to get a failing test if the test code checks database value which should be inserted in exection but in the checking time it was not processed yet?

First of all - you don't have any logging enabled so it's hard to say what is really going on.
Is Spring Boot an option for you? It has built-in logging support. Or are you using just *context library on purpose?

Related

Kotlin class servlet provoke NoClassDefFoundError

In a sample Java servlet project in my IntelliJ IDE, i have created this class in Kotlin :
#WebServlet(name = "TwitterAPIServlet", description = "This is used to test the servlet api", urlPatterns = ["/twitterAPIServlet"])
class TwitterAPIServlet : HttpServlet() {
#Throws(IOException::class)
override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
// Print answer
val out = resp.writer
out.println("Request Done : </br>")
}
}
When i am trying to call this with my .jsp page, i have this error :
2020-05-10 15:30:34.218:WARN:oejs.HttpChannel:qtp60559178-27: /twitterAPIServlet
java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at main.java.co.rezo.api.internal.v1.TwitterAPIServlet.doGet(TwitterAPIServlet.kt)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
When i am trying the same code in Java, it's working :
#WebServlet(
name = "TwitterAPIServlet",
description = "This is used to test the servlet api",
urlPatterns = "/twitterAPIServlet")
public class TwitterAPIServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PrintWriter out = resp.getWriter();
out.println("Request Done : </br>");
}
}
What can i do to make my Kotlin code working?
Most probably the issue is that Kotlin's standard library is not included in the generated WAR (or is not on a classpath if you run the exploded app). Make sure to include it in your build.
Instructions for Gradle can be found in the official examples repository: kotlin-examples.
Maven is similar: https://kotlinlang.org/docs/reference/using-maven.html.
In case of pure IDEA (though it's recommended to use one of the build tools above), check the projects settings:
You should see Kotlin's stdlib included in the artifact:

Camel Route to Upload to S3 fails

Im trying to construct a basic route that detects a .csv file and uploads it to my S3 bucket.
The csv file gets gedected and the route works except of the .to("aws-s3...") part.
I've tried the solution from this question but it fails.
My Route:
public class CsvToS3Route extends RouteBuilder {
#Override
public void configure() throws Exception {
from("file:./src/main/resources/mycsvfilesfolder?filterFile=${file:name.ext.single} =~ 'csv'")
.convertBodyTo(byte[].class)
.setHeader(S3Constants.CONTENT_LENGTH, simple("${in.header.CamelFileLength}"))
.setHeader(S3Constants.KEY,simple("${in.header.CamelFileNameOnly}"))
.to("aws-s3://my-bucket?deleteAfterWrite=false&region=eu-west-1&accessKey=mypublickey&secretKey=RAW(mysecretkey)")
.log("done.");
}}
My Main Class:
#Component
public class CamelRoutes {
Logger logger = LoggerFactory.getLogger(CamelRoutes.class);
private Main main;
private CamelContext context;
#Bean
public void run() throws Exception {
this.main = new Main();
this.context = new DefaultCamelContext(registry);
context.addRoutes(new CsvToS3Route());
main.getCamelContexts().clear();
main.getCamelContexts().add(context);
// Run Camel forever
logger.info("Starting Camel Application");
main.setDuration(-1);
main.run();
}}
The Error
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.apache.camel.support.DefaultComponent.doStart(DefaultComponent.java:245)
The following method did not exist:
org.apache.camel.CamelContext.getPropertiesComponent(Z)Lorg/apache/camel/spi/PropertiesComponent;
The method's class, org.apache.camel.CamelContext, is available from the following locations:
jar:file:/Users/myuser/.gradle/caches/modules-2/files-2.1/org.apache.camel/camel-core/2.23.2.fuse-750029-redhat-00001/93a0f16a539d46373c121d4b10cd9fc844c8779a/camel-core-2.23.2.fuse-750029-redhat-00001.jar!/org/apache/camel/CamelContext.class
jar:file:/Users/myuser/.gradle/caches/modules-2/files-2.1/org.apache.camel/camel-api/3.0.0-M2/7724c277b1f57116083c555ccb3bfd63a4e74ea0/camel-api-3.0.0-M2.jar!/org/apache/camel/CamelContext.class
It was loaded from the following location:
file:/Users/myuser/.gradle/caches/modules-2/files-2.1/org.apache.camel/camel-core/2.23.2.fuse-750029-redhat-00001/93a0f16a539d46373c121d4b10cd9fc844c8779a/camel-core-2.23.2.fuse-750029-redhat-00001.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.apache.camel.CamelContext
2020-02-13 12:53:28.898 INFO 31954 --- [ngupInterceptor] o.a.c.m.MainSupport$HangupInterceptor : Received hang up - stopping the main instance.
2020-02-13 12:53:28.899 INFO 31954 --- [ngupInterceptor] o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.23.2.fuse-750029-redhat-00001 (CamelContext: camel-1) is shutting down
2020-02-13 12:53:28.911 INFO 31954 --- [ngupInterceptor] o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.23.2.fuse-750029-redhat-00001 (CamelContext: camel-1) uptime 0.213 seconds
2020-02-13 12:53:28.911 INFO 31954 --- [ngupInterceptor] o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.23.2.fuse-750029-redhat-00001 (CamelContext: camel-1) is shutdown in 0.012 seconds
Process finished with exit code 1
Is there something I am missing?

How to init " AWSPricing client " by AWSPricingClientBuilder the latest version sdk?

My task is to get aws procuct pricing data, so I do the things as follows:
set the Environment Variables(AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)
fill the pom.xml(in Eclipse) with the code:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-pricing</artifactId>
<version>1.11.513</version>
</dependency>
then I code the test method like the code:
public static void testDescribeServices() {
System.out.println("\n\n begin ....");
AWSPricing client = AWSPricingClientBuilder.standard().withRegion("us-east-1").build();
System.out.println("step 0001");
DescribeServicesRequest servicesRequest = new DescribeServicesRequest();
servicesRequest.setServiceCode("AmazonEC2");
DescribeServicesResult result = client.describeServices(servicesRequest);
List<Service> serviceList = result.getServices();
}
run the method testDescribeServices(), the message on the console is like this: (I was disappointed)
begin ....
17:08:21.166 [main] DEBUG com.amazonaws.AmazonWebServiceClient - Internal logging successfully configured to commons logger: true
17:08:21.831 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.EnvironmentVariableCsmConfigurationProvider#130d63be: Unable to load Client Side Monitoring configurations from environment variables!
17:08:21.831 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.SystemPropertyCsmConfigurationProvider#42a48628: Unable to load Client Side Monitoring configurations from system properties variables!
17:08:21.831 [java-sdk-http-connection-reaper] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Closing connections idle longer than 60000 MILLISECONDS
17:08:21.839 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.ProfileCsmConfigurationProvider#689604d9: The 'default' profile does not define all the required properties!
Exception in thread "main" java.lang.NoSuchMethodError: com.amazonaws.client.AwsSyncClientParams.getAdvancedConfig()Lcom/amazonaws/client/builder/AdvancedConfig;
at com.amazonaws.services.pricing.AWSPricingClient.<init>(AWSPricingClient.java:158)
at com.amazonaws.services.pricing.AWSPricingClient.<init>(AWSPricingClient.java:142)
at com.amazonaws.services.pricing.AWSPricingClientBuilder.build(AWSPricingClientBuilder.java:61)
at com.amazonaws.services.pricing.AWSPricingClientBuilder.build(AWSPricingClientBuilder.java:27)
at com.amazonaws.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)
at com.yunion.apps.metadata.TestAWSDemoAPI.testDescribeServices(TestAWSDemoAPI.java:31)
at com.yunion.apps.metadata.TestAWSDemoAPI.main(TestAWSDemoAPI.java:26)
after trying some setting , I make some progress, and the new method is :
public static void testDescribeServices(String accessKey, String secretKey) {
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials);
AWSPricingClientBuilder builder = AWSPricingClientBuilder.standard();
builder.setCredentials(credentialsProvider);
builder.withRegion("us-east-1");
CsmConfigurationProvider csmConfigurationProvider = new EnvironmentVariableCsmConfigurationProvider();
builder.setClientSideMonitoringConfigurationProvider(csmConfigurationProvider);
System.out.println("step 0001");
AWSPricing awsPricing = builder.build();
System.out.println("step 0002");
DescribeServicesRequest servicesRequest = new DescribeServicesRequest();
servicesRequest.setServiceCode("AmazonEC2");
System.out.println("step 0003");
DescribeServicesResult result = awsPricing.describeServices(servicesRequest);
System.out.println("\n\n step 0004");
List<Service> serviceList = result.getServices();
System.out.println("\n\n step 0005");
}
However, the result is
Exception in thread "main" com.amazonaws.services.pricing.model.AWSPricingException: User: arn:aws:iam::285906155448:user/dev1 is not authorized to perform: pricing:DescribeServices **(Service: AWSPricing; Status Code: 400; Error Code: AccessDeniedException; Request ID: 13155463-4198-11e9-8f92-f1f731c320f2)**

Arquillian - programmatic configuration

I am writing integration tests using Arquillian with embedded glassfish 3.1.2.2 using TestNG. I want to be able to run those tests in parallel, and for this case i need to dynamically configure glassfish ports and database name (we already have this set-up, and I want to reuse it of arquillian tests). What I am missing is a 'before container start' hook, where I could prepare the database, lookup free ports and update my glassfish configuration (domain.xml, could also be glassfish-resources.xml). Is there a 'clean' solution for this, or my usecase was not foreseen by Arquillian developers?
The hacky way I solved it currently is to override arquillian's beforeSuite method but this one gets called twice - at test startup and then in the container (therefore my pathetic static flag). Secondly, this solution would not work for JUnit based tests as there's no way to intercept arquillian's before suite:
public class FullContainerIT extends Arquillian {
private static boolean dbInitialized;
//#RunAsClient <-supported by #Test only
#Override
#BeforeSuite(groups = "arquillian", inheritGroups = true)
public void arquillianBeforeSuite() throws Exception {
if (dbInitialized == false) {
initializeDb();
dbInitialized = true;
}
super.arquillianBeforeSuite();
}
}
Some ideas I had:
+ having #BeforeSuite #RunAsClient seems to be what I need, but #RunAsClient is supported for #Test only;
+ I have seen org.jboss.arquillian.container.spi.event.container.BeforeStart event in Arquillian JavaDocs, but I have no clue how to listen to Arquillian events;
+ I have seen there is a possibility to have #Deployment creating a ShrinkWrap Descriptor, but these do not support Glassfish resources.
I found a clean solution for my problem on JBoss forum. You can register a LoadableExtension SPI and modify the arquillian config (loaded from xml). This is where I can create a database and filter glassfish-resources.xml with proper values. The setup looks like this:
package com.example.extenstion;
public class AutoDiscoverInstanceExtension
implements org.jboss.arquillian.core.spi.LoadableExtension {
#Override
public void register(ExtensionBuilder builder) {
builder.observer(LoadContainerConfiguration.class);
}
}
package com.example.extenstion;
public class LoadContainerConfiguration {
public void registerInstance(#Observes ContainerRegistry, ServiceLoader serviceLoader) {
//Do the necessary setup here
String filteredFilename = doTheFiltering();
//Get the container defined in arquillian.xml and modify it
//"default" is the container's qualifier
Container definition = registry.getContainer("default");
definition.getContainerConfiguration()
.property("resourcesXml", filteredFilename);
}
}
You also need to configure the SPI Extension by creating a file
META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
with this contents:
com.example.extenstion.AutoDiscoverInstanceExtension

NullPointerException and #EJB

I use EJB3+JavaEE6+JBoss. I am absolutely newbie in EJB. I wrote this code:
package server.ejb;
#Remote
public interface HelloUser
{
void sayHello( String name );
}
#Stateless
public class HelloUserBean implements HelloUser
{
#Override public void sayHello( String name )
{
System.out.println( "Hello " + name );
}
}
Having assebled this code with Maven and deployed it on JBoss, I wrote a client:
import server.ejb.HelloUserBean;
import javax.ejb.EJB;
public class Test
{
#EJB
public static HelloUserBean bean;
public static void main( String... args )
{
bean.sayHello( "Alex" );
}
}
After compiling, I've got NullPointerException. It said that bean was null. Using JDNI + PersistentContext I could get a success, but I still can't use DI as well. Please, help me
I reorginized my code! Actually I wrote another server-side project with the same sence and a standalone client-app. Here is the structure of server-side app:
#Remote
public interface EchoRemote{
String getMessage();
}
#Stateless
public class EchoBean implements EchoRemote{
#Override
public String getMessage(){
return "Hello From Stateless Bean";
}
}
public class InvokationClient{
#EJB
private EchoRemote bean;
public String getMessage(){
return bean.getMessage();
}
}
And here is the client-side standalone app:
import com.steeplesoft.client.InvokationClient;
public class Main{
public static void main( String... args ) throws IOException{
InvokationClient client = new InvokationClient();
FileWriter fileWriter = new FileWriter( "D:/invokation_client_test.txt" );
fileWriter.write( client.getMessage() );
fileWriter.close();
}
}
I've got empty file and NullPointerEception in console
I hope you can help me :) It's tremendously important for me!!!
So you start your Test-class standalone in a separate JVM. Where did you configure to which JBoss it should connect? Which component does the dependency injection? Since you don't have a DI container that manages the Test-class and since the connection to JBoss is not configured anywhere, this can't work.
In order to make it work, you can do the following:
1) Write a Servlet, use #EJB in the Servlet and deploy it on JBoss. Put your EJB and the Servlet in the same WAR to make it easy. The Servlet is managed by the container and DI works. As a newbie with EJB I would do this first.
2) Do a JNDI-Lookup and call your EJB from a standalone client as described in https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI
3) Use an Application Client Container (ACC) as described in http://blogs.steeplesoft.com/posts/2011/02/22/java-ees-buried-treasure-the-application-client-container/ Deploy the EAR to jboss and invoke the client locally
$JBOSS_HOME/bin/appclient.sh --host remote://localhost:4447 ./local/path/to/enterpriseapplication-0.1-SNAPSHOT.ear#appclient-0.1-SNAPSHOT.jar
Remark: When I tried the example from blogs.steeplesoft.com, I had problems with the Swing classes, but it did work JBoss EAP 6.2, when I removed the Swing classes.