elasticsearch 6 ESIntegTestCase "codebase property already set" - java

I'm attempting an upgrade to ES 6.2 from 2.3.4.
Previously, we'd integration-tested code by using NodeBuilder and running up a local ES node. I'd rather swap this out for the ESIntegTestCase usage if possible.
However, when I try to run an integration test I get the following error:
at org.elasticsearch.bootstrap.BootstrapForTesting.<clinit>(BootstrapForTesting.java:164)
at org.elasticsearch.test.ESTestCase.<clinit>(ESTestCase.java:190)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.carrotsearch.randomizedtesting.RandomizedRunner$2.run(RandomizedRunner.java:592)
Caused by: java.lang.IllegalStateException: codebase property already set: codebase.metrics-core -> file:/Users/me/.m2/repository/io/dropwizard/metrics/metrics-core/3.1.0/metrics-core-3.1.0.jar, cannot set to file:/Users/me/.m2/repository/com/yammer/metrics/metrics-core/2.2.0/metrics-core-2.2.0.jar
at org.elasticsearch.bootstrap.Security.readPolicy(Security.java:236)
at org.elasticsearch.bootstrap.BootstrapForTesting.<clinit>(BootstrapForTesting.java:139)
... 4 more
What does this mean, and how I can I fix it?
My test class is annotated with: #RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) and extends ESIntegTestCase if that helps at all.
Thank you for any help anyone can offer!

If developing a plugin so still needing embedded ES, then perhaps setting system property -Dtests.gradle=false can work around the issue.
since BootstrapForTesting.java L175 contains:
if (System.getProperty("tests.gradle") == null) {
addClassCodebase(codebases, "plugin-classloader", "org.elasticsearch.plugins.ExtendedPluginsClassLoader");
addClassCodebase(codebases, "elasticsearch-secure-sm", "org.elasticsearch.secure_sm.SecureSM");
}

As per this issue: https://github.com/elastic/elasticsearch/issues/21544 ESIntegTestCase should also no longer really be used unless you're testing a plugin or something like that (see reply posting here: https://discuss.elastic.co/t/how-do-i-deal-with-this-particular-jar-hell-issue/135662/4).
See here for more: https://discuss.elastic.co/t/codebase-property-already-set-when-running-esintegtestcase/135659/2
The best best methodology for integration testing with elasticsearch that I have found now is mentioned in that discuss posting: use testcontainers-elasticsearch (https://github.com/dadoonet/testcontainers-java-module-elasticsearch)
You need docker installed on the machine running the tests, but it will automatically pull the required docker image, start up the container and tear it down again at the end.

Related

Configuring open telemetry for tracing service to service calls ONLY

I am experimenting with different instrumentation libraries but primarily spring-cloud-sleuth and open-telemetry ( OT) are the ones I liked the most. Spring-cloud-sleuth is simple but it will not work for a non-spring ( Jax-RS)project , so I diverted my attention to open telemetry.
I am able to export the metrics using OT, but there is just too much data which I do not need. Spring sleuth gave the perfect solution wherein it just traces the call across microservices and links all the spans with one traceId.
My question is - How to configure OT to get an output similar to spring-sleuth? I tried various configuration and few worked but still the information is huge.
My configuration
-Dotel.traces.exporter=zipkin -Dotel.instrumentation.[jdbc].enabled=false -Dotel.instrumentation.[methods].enabled=false -Dotel.instrumentation.[jdbc-datasource].enabled=false
However, this still gives me method calls and other data. Also, one big pain is am not able to SHUT DOWN metrics data.
gets error like below
ERROR io.opentelemetry.exporter.internal.grpc.OkHttpGrpcExporter - Failed to export metrics. The request could not be executed. Full error message: Failed to connect to localhost/0:0:0:0:0:0:0:1:4317
Anyhelp will be appreciated -
There are 2 ways to configure the open telemetry agent(otel).
Environment variable
Java system property
you can either set
export OTEL_METRICS_EXPORTER=none
or
java -Dotel.metrics.exporter=none app.jar
Reference
https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md

Spring initializer class not found by Tomcat when using Java 16

I have a very simple Gradle (7.0-rc-1) script to initialise a single Spring 5 "hello world" endpoint using an embedded Tomcat instance. The original code is taken from a random example I found on the internet.
My example Gradle project can be found here.
I'm not sure how it works but somehow the web server knows to call the WebApplicationInitializer.onStartup(ServletContext) method on startup so that Spring is intialised.
This works correctly on Java 8; but fails when I change the following toolchain specification in the Gradle build definition to Java 16.
java {
toolchain {
// languageVersion = JavaLanguageVersion.of(16)
languageVersion = JavaLanguageVersion.of(8)
}
}
When using Java 8, Spring is intialised correctly and the endpoint works.
When using Java 16, The onStartup() method is not called, so Spring is not initialised and the endpoint doesn't work (though Tomcat is still started and responds with an error).
The logging shows a message like, there is no stacktrace though:
INFO: No Spring WebApplicationInitializer types detected on classpath
What do I need to do to make this work on Java 16?
Note that I don't want to use spring-boot, please don't suggest it.
I've found a workaround that gets Spring configured and responding to the /hello endpoint. But I don't know why it works or if it's the right thing to do.
If someone can answer the question with an explanation of what's going on with Java 16 - I will gladly mark that as the accepted answer.
Workaround
My work around is to programmatically add the ServletContainerInitializer class.
So where before I was just calling the addWebapp() method:
tomcat.addWebapp("", appBase);
I now add my Spring intializer explicitly:
Context appContext = tomcat.addWebapp("", appBase);
appContext.addServletContainerInitializer(new SpringAppConfig(), null);
Updated code on Github.

Azure release pipeline not picking up variable from nestedStack.yml file

I'm configuring our Release pipeline so that Integration Tests are automatically run after pull requests are merged to master and deployed to Dev environment.
I'm currently getting a connection error, specifically java.net.UnknownHostException: and it looks like my one of my output variables from my nestedStack.yml code is not being imported/read properly:
my-repo/cloud-formation/nestedStack.yml
You can see there is a property there "ApiGatewayInvokeUrl" which is marked as an Output. It is used on Azure DevOps for the "Integration Testing" task in my "Deploy to Dev" stage. It is written as $(ApiGatewayInvokeUrl) as that's how variables on Azure DevOps are used.
This Deploy to Dev will "succeed", however when I further inspect the Integration Tests, I see none actually ran and there was a connection error immediately. I can see it is outputting the variable as $(ApiGatewayInvokeUrl) , so it looks like it just reads it as a String, and never substitutes it for the correct URL value:
I was going off the way another team set up there Integration Tests on a similar pipeline but I might have missed something. Do I need to define $(ApiGatewayInvokeUrl) somewhere in my codebase, or somewhere on Azure? Or am I missing something? I checked the other teams code and didn't see them define it anywhere else, that's why I am ultra confused.
Update: I went into AWS API Gateway and copied the invoke URL and hard-coded that into the Azure DevOps Maven (integration testing) goal path and now it's connecting. So it's 100% just not importing that variable for somer reason.
you need to define\create the variable to use it (unless its an automatic variable, and this one is definitely not an automatic variable). that variable isnt getting substituted because it doesnt exist (afaik).

mysql-connector-java-5.1.23-bin.jar NOT deployed

I am coding my first web app in java and got stuck in db stuff. Followed two tutorials (ref: https://netbeans.org/kb/docs/web/mysql-webapp.html and part1:http://www.javaguicodexample.com/javawebmysqljspjstljsf5.html part2: http://www.javaguicodexample.com/javawebmysqljspjstljsf5_1.html) and got the same issue regarding db config. Crosschecked multiple times and found that mysql-connector-java-5.1.23-bin.jar is there in the desired path and configured properly but is not deployed on running the app. Due to this getting TABLE/VIEW not found.
Kindly help as I am debugging by crosschecking the steps of the provided manuals but its not sufficient.
If you are receiving "TABLE/VIEW not found" that means application is successful in making database connection. There is no such table/view exists in the database.
Regarding dependencies, I would suggest to use some build tool like maven or gradle to make sure all dependencies and versions are managed properly

Arquillian and Selenium in mixed Container/Client mode

i am reading the tutorial on Arquillian's website
http://arquillian.org/guides/functional_testing_using_drone/
Under the paragraph of "Enabling Client Mode" they state that it is possible to mix in-container and client modes in the same test! Just leave off the testable attribute. Any method annotated with #RunAsClient will execute from the client, the remainder will execute inside the container, giving you the best of both worlds!
Here is my Issue.
I want to write a test that users
#Drone
DefaultSelenium browser and
#EJB
MyXXXRepository
I have one test that will add a user to the InMemory database before i have a Selenium test which logs in on the browser with that user...
So in order to get Selenium to work i need to tell the #Deployment to be testable=false, this will cause my #EJB to fail.
So according to the documentation i can skip the testable=false, if i tell the Selenium Test Method that it should run in Client Mode. According to the documentation this should work.
But!!!
This will throw an Exception
Caused by: java.lang.NoClassDefFoundError: Lcom/thoughtworks/selenium/DefaultSelenium;
So i need to be able to tell the
#Drone
DefaultSelenium browser;
To be in Client Mode as well...
Any takers?
Drone is intended to be client side. Personally I've never tried to deploy WebDriver/Drone tests and run it from the server. This sounds a bit crazy :) And obviously since the test itself is mixed classloader complains about the Drone-related imports.
But I have a solution for you which lets you test from the "grey-box" perspective. There is a fairly new extension in Arquillian universe called Warp which allows you to solve your very problem. Here's the guide.
Hope that helps.
I solved the problem by using an import script that will import the user prior to the test, this way i do not need to instantiate the repository and it is now a clean client side test.

Categories