I've got a problem with data driven testing in cucumber. I want to get data from json file. I've prepared scenario:
Feature: data provider
Scenario Outline: Data driven using json file
Given account user
And Get System Variables
And Delete TB report if already exist
When user navigates to TB report
Then Select Filters On Reports Page from <data>
Example:
|data|
|test|
Data json object:
[
{
"fundName": "test",
"currentDate": "31/12/2020"
},
"fundName": "test2",
"currentDate": "31/12/2020"
}
Pojo class for storing data:
public class Data {
public String fundName;
public String currentDate;
}
Data json reader:
private final String path = "path/to/file";
private List<Data> data;
public JsonDataReader(){
DataList = getData();
}
private List<Data> getData() {
Gson gson = new Gson();
BufferedReader bufferReader = null;
try {
bufferReader = new BufferedReader(new FileReader(path));
Data[] data= gson.fromJson(bufferReader, Data[].class);
return Arrays.asList(data);
}catch(FileNotFoundException e) {
throw new RuntimeException("Json file not found at path : " + path);
}finally {
try { if(bufferReader != null) bufferReader.close();}
catch (IOException ignore) {}
}
}
public final Data getDataByName(String name){
return dataList.stream().filter(x -> x.fundName.equalsIgnoreCase(name)).findAny().get();
}
Step definition:
#Then("Select Filters On Reports Page from \\\"(.*)\\\"$")
public void selectMultipleFilters(String name) {
Data data = FileReaderManager.getInstance().getJsonDataReader().getFundByName(name);
reportSteps.selectMultipleFiltersForReports(data);
}
But when I try to run this I've got an error on 5th step:
java.util.NoSuchElementException: No value present
at JsonDataReader.getDataByName
Can someone tell me what am I doing wrong?
Related
Here's my method where im reading json file.
private void LoadTabaksFromJson() {
InputStream raw = mContext.getResources().openRawResource(R.raw.tabaks);
Reader reader = new BufferedReader(new InputStreamReader(raw));
ListOfTabaks listOfTodos = new Gson().fromJson(reader, ListOfTabaks.class);
List<Tabak> todoList = listOfTodos.getTodoArrayList();
for (Tabak item: todoList){
mDataBase.insert(TabakTable.NAME,null,getContentValues(item));
}
}
public class ListOfTabaks {
protected ArrayList<Tabak> tabakArrayList;
public ArrayList<Tabak> getTodoArrayList(){
return tabakArrayList;
}
}
And Exeption
Caused by: java.lang.NullPointerException: Attempt to invoke interface
method 'java.util.Iterator java.util.List.iterator()' on a null object
reference
at
com.hookah.roma.hookahmix.TabakLab.LoadTabaksFromJson(TabakLab.java:61)
at com.hookah.roma.hookahmix.TabakLab.(TabakLab.java:32)
at com.hookah.roma.hookahmix.TabakLab.get(TabakLab.java:37)
at
com.hookah.roma.hookahmix.TabakListFragment.updateUI(TabakListFragment.java:38)
at
com.hookah.roma.hookahmix.TabakListFragment.onCreateView(TabakListFragment.java:32)
at
android.support.v4.app.Fragment.performCreateView(Fragment.java:2184)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1298)
at
android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at
android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
And json file :
{
"tabaksArrayList":[
{
"name":"Абрикос",
"description":"Со вкусом Абрикоса",
"rating":"4.1",
"favourite":"1",
"family":"Al fakher"
},
{
"name":"Ананас",
"description":"Со вкусом Ананаса",
"rating":"4.1",
"favourite":"1",
"family":"Al fakher"
},
{
"name":"Апельсин",
"description":"Со вкусом Апельсина",
"rating":"4.1",
"favourite":"1",
"family":"Al fakher"
},
{
"name":"Апельсин с мятой",
"description":"Со вкусом Апельсина с мятой",
"rating":"4.1",
"favourite":"1",
"family":"Al fakher"
},
It looks like your json schema issue, i'm guessing listOfTodos return null. You can refer to this to generate your schema.
But sometimes that tools can make us confuse so i tried to create your schema manually like this:
TabakRoot.java
public class TabakRoot {
#SerializedName("tabaksArrayList")
private List<TabakItem> tabakItem = null;
public List<TabakItem> getTabakItem() {
return tabakItem;
}}
TabakItem.java
public class TabakItem {
#SerializedName("family")
#Expose
private String tabakFamily;
public String getTabakFamily() {
return tabakFamily;
}}
finally
TabakRoot listOfTodos = new Gson().fromJson(reader, TabakRoot.class);
List<TabakItem> todoList = listOfTodos.getTabakItem();
Looks like you are not initialising your ArrayList, try changing:
protected ArrayList<Tabak> tabakArrayList;
for:
protected ArrayList<Tabak> tabakArrayList = new ArrayList<>();
Please put your json file in assets folder
use AsyncTask to protect from ANR like situtation
onBackground(){
String json = null;
try {
InputStream stream = activity.getAssets().open("ur_json_file_in_assets_folder.json");
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
stream.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return json;
}
then parse in
onPostExecute(String str){
JsonObject object = new JsonObject(str);
JsonArray arr = object.getJsonArray("tabaksArrayList");
...}
more details at ParseJsonFileAsync.java
You're not initialising tabakArrayList, add a constructor to your ListOfTabaks as following
public ListOfTabaks{
tabakArrayList = new ArrayList<>();
}
and you should be fine
I am very new to Vaadin, REST and Vertx. I want to post the data into MYSQL db from a JSON file. So I have created a base url "localhost:1443" and am able to call the handler in the other project where db is connected. But don't know to to pass the JSON file my current project to the another project where the MYSQL is configured.
Here am calling the method which is defined in REST,
public OutputStream receiveUpload(String filename, String mimeType) {
FileOutputStream fos = null; // Output stream to write to
file = new
File(VaadinService.getCurrent().getBaseDirectory().getAbsolutePath()
+"/Jsonfile/" + filename);
FILE_PATH =
VaadinService.getCurrent().getBaseDirectory().getAbsolutePath()
+"/Jsonfile/" + filename;
try{
fos = new FileOutputStream(file);
JSONArray products =
productsDataProvider.uploadCatalogs(file.toString());
Notification.show("Succesfully converted :)");
}
catch (final java.io.FileNotFoundException e) {
// Error while opening the file. Not reported here.
e.printStackTrace();
return null;
}
return fos; // Return the output stream to write to
}
this is where I defined method,
public JSONArray uploadCatalogs(String catalogClass) {
return dataProviderUtil.getResourceArray("gapi/upload_products", new
HashMap<String, String>(){
{
put("class", catalogClass);
}
});
This is the product handler in another project,
router.mountSubRouter("/gapi/upload_products", new
UploadCatalog(VertxInstance.get()));
Here the class defined,
public class UploadCatalog extends AbstractRouteHandler {
private final static Logger LOG =
LogManager.getLogger(UploadCatalog.class);
public UploadCatalog(Vertx vertx) {
super(vertx);
this.route().handler(BodyHandler.create());
this.get("/").handler(this::upload);
}
private void upload(RoutingContext routingContext) {
LOG.info("hello");
}
i can see the logger info in console...
I tried the below one,
private void upload(RoutingContext routingContext) {
JsonObject paramsObject = routingContext.getBodyAsJson();
JsonObject result = new JsonObject();
Integer id = LocalCache.getInstance().store(new
QueryData("product.insert", paramsObject));
LOG.info("Executing query:" + "product.insert" );
vertx.eventBus().send(DatabaseService.DB_QUERY, id,
(AsyncResult<Message<Integer>> res) -> {
QueryData resultData = (QueryData)
LocalCache.getInstance().remove(res.result().body());
if (resultData.errorFlag ||
resultData.updateResult.getUpdated() == 0) {
/*result.put("status", "error").put("error", "Error
in creating user profile.");
response.putHeader("content-type",
"application/json").end(result.encode());*/
} else {
/*LOG.info("Insert query (ms):" +
resultData.responseTimeInMillis);
this.sendNewUserProfile(data, response);*/
}
});
}
How to insert data in mysql db from JSON file?
So I already succeed with one Json to get it all worked. Now I have another class where I want to get only one attribute. I have now a moviedatabase class (which work with JSON and gets all the information) and now I want to add a Trailer which is from Youtube API. so basically I need it to be added into the same JSON to make it easier for me in the future to get it into a HTML. the only problem is I cant get it work. I get a syntax error JSON when using this method.
EDIT CODE 1.1:
Youtube attribute:
public class FilmAttribut {
private String title = "";
private String release = "";
private int vote = 0;
private String overview = "";
private String poster = "";
private String trailer = "";
// getters + setters stripped
}
Youtube class:
public class Youtube {
FilmAttribut movie = new FilmAttribut();
public void search(String trailer, FilmAttribut in) {
HttpResponse<JsonNode> response;
try {
response = Unirest.get("https://www.googleapis.com/youtube/v3/search?key=[app key here]&part=snippet")
.queryString("q", trailer + " trailer")
.asJson();
JsonNode json = response.getBody();
JSONObject envelope = json.getObject();
JSONArray items = envelope.getJSONArray("items");
in.setTrailer("https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId")); //Gives me error here
}
catch (JSONException e) {
e.printStackTrace();
} catch (UnirestException e) {
e.printStackTrace();
}
return null;
}
}
and main method
public class WebService {
public static void main(String[] args) {
setPort(1337);
Gson gson = new Gson();
Youtube yt = new Youtube();
MovieDataBase mdb = new MovieDataBase();
get("/search/:movie", (req, res) -> {
String titel = req.params(":movie");
FilmAttribut film = mdb.searchMovie(titel);
yt.search(titel, film);
String json = gson.toJson(film);
return json;
});
So I think the problem is that you can't have two gson.toJson(film) + gson.toJson(trailer); Because it makes the JSON twice, where one time is for the film (aka. movie) and then a new json is created with trailer which make the syntax error.
So my real question is, is it possible to have another class like I have now youtube. to send the information to a attribute class where I have all my attributes and then run it in main-method so that I can get all the JSON in one JSON.
If I did understand well what you are asking, yes you can, but I would do something like that instead:
public void search(String trailer, FileAttribut in) {
// fetch the trailer from youtube (NB: you should use getters/setters, not public fields)
in.setTrailer("https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId"));
}
and:
FilmAttribut film = mdb.searchMovie(titel);
yt.search(titel, film); // pass "film" to "fill" its trailer
return gson.toJson(film);
OR
public String search(String trailer) {
// fetch the trailer from youtube
return "https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId");
}
and:
FilmAttribut film = mdb.searchMovie(titel);
film.setTrailer(yt.search(titel));
return gson.toJson(film);
I am trying to convert java object to json. I have a java class which reads a specific column from a text file. And I want to store that read column in json format.
Here is my code. I dont know where I am going wrong.
Thanks in advance.
File.java
public class File {
public File(String filename)
throws IOException {
filename = readWordsFromFile("c:/cbir-2/sample/aol.txt");
}
public String value2;
public String readWordsFromFile(String filename)
throws IOException {
filename = "c:/cbir-2/sample/aol.txt";
// Creating a buffered reader to read the file
BufferedReader bReader = new BufferedReader(new FileReader(filename));
String line;
//Looping the read block until all lines in the file are read.
while ((line = bReader.readLine()) != null) {
// Splitting the content of tabbed separated line
String datavalue[] = line.split("\t");
value2 = datavalue[1];
// System.out.println(value2);
}
bReader.close();
return "File [ list=" + value2 + "]";
}
}
GsonExample.java
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args)
throws IOException {
File obj = new File("c:/cbir-2/sample/aol.txt");
Gson gson = new Gson();
// convert java object to JSON format,
// and returned as JSON formatted string
String json = gson.toJson(obj);
try {
//write converted json data to a file named "file.json"
FileWriter writer = new FileWriter("c:/file.json");
writer.write(json);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(json);
}
}
I recommend you to use
Jackson
High-performance JSON processor.
from http://jackson.codehaus.org/
here is the sample from their tutorial
The most common usage is to take piece of JSON, and construct a Plain Old Java Object ("POJO") out of it. So let's start there. With simple 2-property POJO like this:
// Note: can use getters/setters as well; here we just use public fields directly:
public class MyValue {
public String name;
public int age;
// NOTE: if using getters/setters, can keep fields `protected` or `private`
}
we will need a com.fasterxml.jackson.databind.ObjectMapper instance, used for all data-binding, so let's construct one:
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
The default instance is fine for our use -- we will learn later on how to configure mapper instance if necessary. Usage is simple:
MyValue value = mapper.readValue(new File("data.json"), MyValue.class);
// or:
value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class);
// or:
value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);
And if we want to write JSON, we do the reverse:
mapper.writeValue(new File("result.json"), myResultObject);
// or:
byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
// or:
String jsonString = mapper.writeValueAsString(myResultObject);
Processing a file that have the information in columns like a csv I recomend for this task use opencsv here is an example for information in 5 columns separated by '|'
import com.opencsv.CSVReader;
import pagos.vo.UserTransfer;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* Created by anquegi on
*/
public class CSVProcessor {
public List<String[]> csvdata = new ArrayList<String[]>();
public CSVProcessor(File CSVfile) {
CSVReader reader = null;
try {
reader = new CSVReader(new FileReader(CSVfile),'|');
} catch (FileNotFoundException e) {
e.printStackTrace();
Logger.error("Cannot read CSV: FileNotFoundException");
}
String[] nextLine;
if (reader != null) {
try {
while ((nextLine = reader.readNext()) != null) {
this.csvdata.add(nextLine);
}
} catch (IOException e) {
e.printStackTrace();
Logger.error("Cannot read CSV: IOException");
}
}
}
public List<TransfersResult> extractTransfers() {
List<TransfersResult> transfersResults = new ArrayList<>();
for(String [] csvline: this.csvdata ){
if(csvline.length >= 5){
TransfersResult transfersResult = new TransfersResult(csvline[0]
,csvline[1],csvline[2],csvline[3],csvline[4]);
// here transfersResult is a pojo java object
}
}
return transfersResults;
}
}
and for returning a json from a servlet this is solved in this question in stackoverflow
How do you return a JSON object from a Java Servlet
Looks like you might be overwriting value2 for each line.
value2= datavalue[1];
EDIT: Can you make value2 a List and add to it.
value2.add(datavalue[1]);
EDIT2: You need to check the size of the array before using it.
if (datavalue.length >= 2){
value2.add(datavalue[1]);
}
The reason for the exception could be
value2=datavlue[1];
means during your first execution of while loop , you are trying to assign seconds element(datavalue[1]) in the String array to value2 , which is not created by then.So its giving that exception.
I'm trying to group the results so that they are grouped by category.
SearchResponse response = client.prepareSearch("search")
.addAggregation(AggregationBuilders.terms("category").field("category").size(0))
.execute()
.actionGet();
The code above creates aggregations but I'm running into a problem where strings with hyphens in them are being separated and put into their own 'Bucket'.
From what I've read I need to change the mapping settings so that the category is not analysed but I'm not sure how to do this. Is this done when writing to Elasticsearch or when reading? How is it set exactly?
To apply elasticsearch mapping using java api,
STEP 1) First create your mapping for the Elasticsearch type in a json file,
eg. resources/Customer.json
{
"Customer" : {
"settings" : {
},
"properties" : {
"category" : { "type":"String" , "index" : "not_analyzed"}
}
}
}
}
}
STEP 2) create a java method to apply mapping from a json file, (see complete example here)
class EsUtils {
public static Client client
public static void applyMapping(String index, String type, String location) throws Exception {
String source = readJsonDefn(location);
if (source != null) {
PutMappingRequestBuilder pmrb = client.admin().indices()
.preparePutMapping(index)
.setType(type);
pmrb.setSource(source);
MappingListener mappingListener = new MappingListener(pmrb)
// Create type and mapping
Thread thread = new Thread(mappingListener)
thread.start();
while (!mappingListener.processComplete.get()) {
System.out.println("not complete yet. Waiting for 100 ms")
Thread.sleep(100);
}
} else {
System.out.println("mapping error");
}
}
public static String readJsonDefn(String url) throws Exception {
//implement it the way you like
StringBuffer bufferJSON = new StringBuffer();
FileInputStream input = new FileInputStream(new File(url).absolutePath);
DataInputStream inputStream = new DataInputStream(input);
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = br.readLine()) != null) {
bufferJSON.append(line);
}
br.close();
return bufferJSON.toString();
}
}
STEP 3) call applyMapping() method passing your es client,
String index = "search"; //yourIndex
String type = "Customer";
String location = "resources/Customer.json";
EsUtils.client = yourClient; //pass your client
EsUtils.applyMapping(index, type, location);
STEP 4) query as you want,
SearchRequestBuilder builder = client.prepareSearch("search");
builder.addAggregation(AggregationBuilders.terms("categoryterms")
.field("category").size(0))
SearchResponse response = builder.execute().actionGet();
Complete Reference
Elasticsearch apply mapping