My Unit Test project is running into an error when configured with Jenkins. The Tests run fine when I run the maven test locally from Command prompt.
Error I get :
feature ("Verify GET User Details API")
cucumber.runtime.CucumberException: java.lang.IllegalStateException: Failed to create cache dir
at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:78)
at com.ibm.wce.scbn.cc.runner.BaseRunner.feature(BaseRunner.java:32)
Caused by: java.lang.IllegalStateException: Failed to create cache dir
at io.vertx.core.file.impl.FileResolver.setupCacheDir(FileResolver.java:332)
at io.vertx.core.file.impl.FileResolver.<init>(FileResolver.java:87)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:165)
at io.vertx.core.impl.VertxImpl.vertx(VertxImpl.java:92)
at io.vertx.core.impl.VertxFactoryImpl.vertx(VertxFactoryImpl.java:40)
at io.vertx.core.impl.VertxFactoryImpl.vertx(VertxFactoryImpl.java:32)
at io.vertx.core.impl.VertxFactoryImpl.vertx(VertxFactoryImpl.java:27)
at io.vertx.core.Vertx.vertx(Vertx.java:75)
at com.ibm.wce.scbn.cc.util.TokenUtil.<init>(TokenUtil.java:32)
at com.ibm.wce.scbn.cc.util.TokenUtil.getInstance(TokenUtil.java:46)
at com.ibm.wce.scbn.cc.stepdefinitions.AccountsByID.we_send_Get_request_to_service_for_Account_with_source_and_iui(AccountsByID.java:369)
at ✽.We send Get request to service for Account "1" with source "1" and iui "1"(./features/AccountsByID/AccountsByID.feature:7)
TokenUtil.java
public class TokenUtil {
private static final Logger LOGGER = Logger.getLogger(TokenUtil.class.getName());
private static TokenUtil TOKEN_INSTANCE = null;
private static Vertx VERTX = null;
private static JWTAuthOptions JWTAUTHOPS = new JWTAuthOptions();
private TokenUtil() throws Exception {
try {
VERTX = Vertx.vertx();
JsonObject objJason = new JsonObject(VERTX.fileSystem().readFileBlocking(System.getProperty("privatejwtpath")));
JWTAUTHOPS.addJwk(objJason);
} catch (Exception e) {
LOGGER.error("Unable to load private JWK json file", e);
throw e;
}
}
public static TokenUtil getInstance() throws Exception {
if (TOKEN_INSTANCE == null) {
synchronized (TokenUtil.class) {
TOKEN_INSTANCE = new TokenUtil();
}
}
return TOKEN_INSTANCE;
}
public String getJWT(String iui) {
JWTOptions jwtOptions = new JWTOptions();
JsonObject payLoad = new JsonObject();
jwtOptions.setAlgorithm("RS256");
jwtOptions.setExpiresInSeconds(300);
JWTAuth jwt = JWTAuth.create(VERTX, JWTAUTHOPS);
payLoad.put("ibm", new JsonObject().put("iui", iui));
return jwt.generateToken(payLoad, jwtOptions);
}
}
Any suggestions on how to fix this is highly appreciated. Thank you
Issue fixed by disabling Cache
Related
I have a quarkus REST API project with a situation where i need to execute a part of my code in a new process (not new thread, because the hibernate context gets lost in the new thread for database operations) when a call to an API endpoint is made, but i do not want to extract this code into a whole new project so i can generate a separate .jar file i can execute as a new process. Instead, i saw that you can start a class in your own project as a new process here:
https://dzone.com/articles/running-a-java-class-as-a-subprocess
My calling code (the endpoint) looks like this:
package com.example.platform.bot.api;
...(imports)
#Path("/jobs")
public class JobResource {
#Inject JobBuilder jobBuilder;
#Inject JobRepository jobRepository;
#Inject JobRunnerProcessCaller jobRunnerProcessCaller;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Job createJob(#Valid JobRequest jobRequest) throws Exception {
Job rawJob = jobBuilder.buildJobFromJobRequest(jobRequest);
Job job = jobRepository.persistWithCheckedDbConnections(rawJob);
jobRunnerProcessCaller.callJobRunnerFor(job);
return job;
}
}
Basically, the JobRunnerProcessCaller component in the createJob method starts the new process from a class that is in the same project and package (directly next to it):
package com.example.platform.bot;
...(imports)
#ApplicationScoped
public class JobRunnerProcessCaller {
public void callJobRunnerFor(final Job job) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder(getCommandWithArgumentList(job));
processBuilder.inheritIO();
processBuilder.start();
}
private List<String> getCommandWithArgumentList(Job job) {
List<String> command = new ArrayList<>();
command.add(getJavaBinaryPath());
command.add("-cp");
command.add(System.getProperty("java.class.path"));
command.add(JobRunnerProcessExecutor.class.getName());
command.add(job.getId().toString());
return command;
}
private String getJavaBinaryPath() {
String javaHome = System.getProperty("java.home");
return String.format("%s%sbin%sjava", javaHome, File.separator, File.separator);
}
}
The code (class JobRunnerProcessExecutor looks like this (with a main method, as required to be run/started in a new process):
package com.example.platform.bot;
...(imports)
public class JobRunnerProcessExecutor {
#Inject BotRepository botRepository;
#Inject JobRepository jobRepository;
#Inject SettingRepository settingRepository;
#Inject JobRunner jobRunner;
#ConfigProperty(name = "bot.id") Long ownBotId;
public static void main(String[] args) {
try {
JobRunnerProcessExecutor executor = buildExecutorFromCDI();
Job job = executor.getValidatedJobFromArguments(args);
executor.tryToExecuteJobRunnerFor(job);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static JobRunnerProcessExecutor buildExecutorFromCDI() {
return CDI.current()
.select(JobRunnerProcessExecutor.class).get();
}
private void tryToExecuteJobRunnerFor(Job job) {
Bot bot = botRepository.getById(ownBotId);
jobRunner.setSettings(settingRepository.getActiveSettings());
WebScraper webScraper = new BaiduWebScraper(new JsoupAdapter(), bot.getBaseUrl());
jobRunner.runJob(job, webScraper);
}
private Job getValidatedJobFromArguments(String[] args) throws Exception {
if (args.length != 1) throw new Exception("Missing job ID argument for job runner process");
Long jobId = Long.parseLong(args[0]);
Job job = jobRepository.getById(jobId);
if (job == null) throw new Exception("Could not find job matching passed ID");
return job;
}
}
Everything else executes fine, with no exception or error on the API endpoint process. However, if i look at the output console i can see the exception message being printed from the JobRunnerExecutor process:
Error: Could not find or load main class com.example.platform.bot.JobRunnerProcessExecutor Caused by: java.lang.ClassNotFoundException: com.example.platform.bot.JobRunnerProcessExecutor
I do not understand how he was unable to load this class, if it is laying directly next to the calling class in the same package. What is going wrong here with the process call?
Edit: It says "could not load main class", but the class has a correct main method, right?.
Someone please help me i keep trying but not able to find out why i am unable to get the results.
I have created this java springboot web service where when I run the java application, a web browser page will open and when I type in the URL e.g localhost:8080/runbatchfileparam/test.bat the program will check if the test.bat file exist first. If it does, the web page will show a JSON result {“Result”: true} and the command in the batch file will be executed. If it does not exist, the web page will show {“Result”: false}.
I want to create an ASP.NET Web Service that will use the function created in the java web service. When I run the ASP.NET Web Application, a web browser page will open. User will type in URL something like this: localhost:12345/api/callbatchfile/test.bat. The java web service should be running and I should get either {“Result”: true} or {“Result”: false} when I run the C# ASP.NET Web Application too.
However I only get an empty {} without anything inside the brackets. Why is that so?
Here are my code in ASP.NET
TestController.cs
private TestClient testClient = new TestClient();
public async Task<IHttpActionResult> GET(string fileName)
{
try
{
var result = await testClient.runbatchfile(fileName);
var resultDTO = JsonConvert.DeserializeObject<TestVariable>(result);
return Json(resultDTO);
}
catch (Exception e)
{
var result = "Server is not running";
return Ok(new { ErrorMessage = result });
}
}
TestVariable.cs
public class TestVariable
{
public static int fileName { get; set; }
}
TestClient.cs
private static HttpClient client;
private static string BASE_URL = "http://localhost:8080/";
static TestClient()
{
client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> runbatchfile(string fileName)
{
var endpoint = string.Format("runbatchfile/{0}", fileName);
var response = await client.GetAsync(endpoint);
return await response.Content.ReadAsStringAsync();
}
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "TestBatchClient",
routeTemplate: "api/runbatchfile/{fileName}",
defaults: new { action = "GET", controller = "Test" }
);
Someone please do help me. Thank you so much.
EDIT
Java web service
Application.java
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
BatchFileController.java
private static final String template = "Sum, %s!";
#RequestMapping("/runbatchfile/{param:.+}")
public ResultFormat runbatchFile(#PathVariable("param") String fileName) {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch(fileName);
}
ResultFormat
private boolean result;
public ResultFormat(boolean result) {
this.result = result;
}
public boolean getResult() {
return result;
}
RunBatchFile.java
public ResultFormat runBatch(String fileName) {
String var = fileName;
String filePath = ("C:/Users/attsuap1/Desktop/" + var);
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return new ResultFormat(exitVal == 0);
} catch (Exception e) {
e.printStackTrace();
return new ResultFormat(false);
}
}
I am not sure if this helps.. but I suspect that the AsyncTask is not really executing...
var result = await testClient.testCallBatchProject(fileName);
I would try something like below:
await testClient.testCallBatchProject(fileName).Delay(1000);
Can you try and check if the same happens for a synchronous call? .. if it does, we can zero down on the above.
I have written a RESTful API using Apache Jersey. I am using MongoDB as my backend. I used Morphia (v.1.3.4) to map and persist POJO to database. I tried to follow "1 application 1 connection" in my API as recommended everywhere but I am not sure I am successful. I run my API in Tomcat 8. I also ran Mongostat to see the details and connection. At start, Mongostat showed 1 connection to MongoDB server. I tested my API using Postman and it was working fine. I then created a load test in SoapUI where I simulated 100 users per second. I saw the update in Mongostat. I saw there were 103 connections. Here is the gif which shows this behaviour.
I am not sure why there are so many connections. The interesting fact is that number of mongo connection are directly proportional to number of users I create on SoapUI. Why is that? I found other similar questions but I think I have implemented there suggestions.
Mongo connection leak with morphia
Spring data mongodb not closing mongodb connections
My code looks like this.
DatabaseConnection.java
// Some imports
public class DatabaseConnection {
private static volatile MongoClient instance;
private static String cloudhost="localhost";
private DatabaseConnection() { }
public synchronized static MongoClient getMongoClient() {
if (instance == null ) {
synchronized (DatabaseConnection.class) {
if (instance == null) {
ServerAddress addr = new ServerAddress(cloudhost, 27017);
List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
MongoCredential credentia = MongoCredential.createCredential(
"test", "test", "test".toCharArray());
credentialsList.add(credentia);
instance = new MongoClient(addr, credentialsList);
}
}
}
return instance;
}
}
PourService.java
#Secured
#Path("pours")
public class PourService {
final static Logger logger = Logger.getLogger(Pour.class);
private static final int POUR_SIZE = 30;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response createPour(String request)
{
WebApiResponse response = new WebApiResponse();
Gson gson = new GsonBuilder().setDateFormat("dd/MM/yyyy HH:mm:ss").create();
String message = "Pour was not created.";
HashMap<String, Object> data = null;
try
{
Pour pour = gson.fromJson(request, Pour.class);
// Storing the pour to
PourRepository pourRepository = new PourRepository();
String id = pourRepository.createPour(pour);
data = new HashMap<String, Object>();
if ("" != id && null != id)
{
data.put("id", id);
message = "Pour was created successfully.";
logger.debug(message);
return response.build(true, message, data, 200);
}
logger.debug(message);
return response.build(false, message, data, 500);
}
catch (Exception e)
{
message = "Error while creating Pour.";
logger.error(message, e);
return response.build(false, message, new Object(),500);
}
}
PourDao.java
public class PourDao extends BasicDAO<Pour, String>{
public PourDao(Class<Pour> entityClass, Datastore ds) {
super(entityClass, ds);
}
}
PourRepository.java
public class PourRepository {
private PourDao pourDao;
final static Logger logger = Logger.getLogger(PourRepository.class);
public PourRepository ()
{
try
{
MongoClient mongoClient = DatabaseConnection.getMongoClient();
Datastore ds = new Morphia().map(Pour.class)
.createDatastore(mongoClient, "tilt45");
pourDao = new PourDao(Pour.class,ds);
}
catch (Exception e)
{
logger.error("Error while creating PourDao", e);
}
}
public String createPour (Pour pour)
{
try
{
return pourDao.save(pour).getId().toString();
}
catch (Exception e)
{
logger.error("Error while creating Pour.", e);
return null;
}
}
}
When I work with Mongo+Morphia I get better results using a Factory pattern for the Datastore and not for the MongoClient, for instance, check the following class:
public DatastoreFactory(String dbHost, int dbPort, String dbName) {
final Morphia morphia = new Morphia();
MongoClientOptions.Builder options = MongoClientOptions.builder().socketKeepAlive(true);
morphia.getMapper().getOptions().setStoreEmpties(true);
final Datastore store = morphia.createDatastore(new MongoClient(new ServerAddress(dbHost, dbPort), options.build()), dbName);
store.ensureIndexes();
this.datastore = store;
}
With that approach, everytime you need a datastore you can use the one provided by the factory. Of course, this can implemented better if you use a framework/library that support factory pattern (e.g.: HK2 with org.glassfish.hk2.api.Factory), and also singleton binding.
Besides, you can check the documentation of MongoClientOptions's builder method, perhaps you can find a better connection control there.
Below I have a code snippet for a custom API manager mediator, I'm suppose to modify this code for our use. I'm having trouble though getting the logs out of the code when I'm running it in our wso2 environment. What would be the process to be able to the outputs of these logs. This is going to be a jar file I add to the repository/components/lib/ directory of the APIM. The jar file name is com.domain.wso2.apim.extensions. I need to be able to see whats being passed and what parts of the code are being hit for testing
public class IdentifiersLookup extends AbstractMediator implements ManagedLifecycle {
private static Log log = LogFactory.getLog(IdentifiersLookup.class);
private String propertyPrefix = "";
private String netIdPropertyToUse = "";
private DataSource ds = null;
private String DsName = null;
public void init(SynapseEnvironment synapseEnvironment) {
if (log.isInfoEnabled()) {
log.info("Initializing IdentifiersLookup Mediator");
}
if (log.isDebugEnabled())
log.debug("IdentifiersLookup: looking up datasource" + DsName);
try {
this.ds = (DataSource) new InitialContext().lookup(DsName);
} catch (NamingException e) {
e.printStackTrace();
}
if (log.isDebugEnabled())
log.debug("IdentifiersLookup: acquired datasource");
}
Add the below line to log4j.properties file resides wso2am-2.0.0/repository/conf/ folder and restart the server.
log4j.logger.com.domain.wso2.apim.extensions=INFO
Im trying to user the following code to complete a task in jbpm:
private static RemoteRestRuntimeEngineFactory restSessionFactory = null;
private static RuntimeEngine engine = null;
private static KieSession ksession = null;
private static TaskService task = null;
public static void main(String[] args) {
try {
restSessionFactory = RemoteRestRuntimeEngineFactory.newRestBuilder()
.addUrl(new URL("http://localhost:8080/jbpm-console"))
.addDeploymentId("jbpm:formularios:1.2")
.addUserName("admin")
.addPassword("admin").buildFactory();
} catch (InsufficientInfoToBuildException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
engine = restSessionFactory.newRuntimeEngine();
ksession = engine.getKieSession();
task = engine.getTaskService();
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", "mary");
map.put("age", "23");
task.complete(271, "admin", map);
}
Im have only this dependency:
<dependency>
<groupId>org.kie.remote</groupId>
<artifactId>kie-remote-client</artifactId>
<version>6.2.0.Beta3</version>
</dependency>
The taks complete without problem but the the parameters are empty;
Then i tried to use the "PostMan" (Chrome plugin) to do the following POST:
localhost:8080/jbpm-console/rest/task/249/complete?map_name=mary&map_idade=23
and the task complete without problem but with parameters.
If i start a new process:
localhost:8080/jbpm-console/rest/runtime/jbpm:formularios:1.0/process/formularios.isluis/start?map_nome=mary&map_idade=23
The process start with the correct parameters.
Im using Jbpm-console 6.1
Am I missing something???
This is an issue in the client, there's a line missing in https://github.com/droolsjbpm/droolsjbpm-integration/blob/6.2.0.Beta3/kie-remote/kie-remote-client/src/main/java/org/kie/services/client/api/command/TaskServiceClientCommandObject.java#L261
It should also do cmd.setData(values). Fixing on master now.