How to get the actual values from OutboundJaxrsResponse in java? - java

In my RestClient returns below response to my jersey service.
OutboundJaxrsResponse{status=200, reason=OK, hasEntity=true, closed=false, buffered=false}
The above one returns the list. How can I get the list and how to validate each record id? If id is not available in my database need to store missing id. how to handle this?
Below is my code;
public Response list() throws Exception {
Response response = null;
RestClient client = service.getClient();
try {
response = client.invokeServiceGETForArray(serviceType, "/test/name", null, null);
JsonArray responseLst = (JsonArray) response.readEntity(JsonArrayBuilder.class);
System.out.println("Response Array List :: " + responseLst);
} catch (Exception e) {
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getLocalizedMessage()).build();
}
return response;
}
above code snippet returns the below response :
OutboundJaxrsResponse{status=200, reason=OK, hasEntity=true, closed=false, buffered=false}
I am trying to read response using below code :
JsonArray responseLst = (JsonArray) response.readEntity(JsonArrayBuilder.class);
But it is throwing below exception.
java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)
Thanks in advance,

Related

Get the document from solr using specific attribute value

I am new to solr. I am using solr which has data.Now I want to get the data of a particular document by searching into the solr. I have an attribute value with which I want to search in the solr. I am doing this by java. I have tried all the solution from web but not working.
public void searchQuery(String valuetobesearched) throws UnsupportedEncodingException {
server = new SolarConnectionClass().getSolrInstance("URL of my solr");
SolrQuery sQueryParams = new SolrQuery();
//String queryString = "*:*";
sQueryParams.setQuery("name:"+URLEncoder.encode(valuetobesearched));
//sQueryParams.addFilterQuery("name:"+URLEncoder.encode(valuetobesearched));
/*sQueryParams.setStart(0);
sQueryParams.setRows(5000);*/
//sQueryParams.set("defType", "edismax");
//sQueryParams.set
QueryResponse response = null;
try {
System.out.println(sQueryParams);
response = server.query(sQueryParams);
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
SolrDocumentList results = response.getResults();
System.out.println(results.size());
/*if(results.size() > 0) {
for (int i = 0; i < results.size(); ++i) {
SolrDocument sortedDocument = results.get(0);
System.out.println(sortedDocument.getFieldValue("PQR"));
}
}
*/
}
How can do this ?
You don't have encode parameters when using SolrQuery class.
Just set the query in this way the client will transparently do the "dirty" job:
sQueryParams.setQuery("name:" + valuetobesearched);
Again, you can see the total number of results found using:
response.getResults().getNumFound()
The size of response.getResults() depends from the setRows parameter (that in your post is commented).
In order to understand how Solr query works, I suggest to make your tests using your browser and then transpose that requests to SolrJ.
For example the url that comes out from of your post is:
http://localhost:8983/solr/collection1/select?q=name:hello

How to connect to ElasticSearch with Java transport client?

I am following the ElasticSearch documentation on Java Client. I have started ElasticSearch and I can interact with it with the Rest API. I want to use the Java Client and so far I have a main like this:
public class TestElastic {
public static void main(String[] args) {
try{
TransportClient client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
JSONObject place = new JSONObject();
place.put("name", "AAAAA");
IndexResponse response = client.prepareIndex("my_database", "places", "1")
.setSource(place)
.get();
System.out.println(response.toString());
// Index name
String _index = response.getIndex();
System.out.println(_index);
// Type name
String _type = response.getType();
System.out.println(_type);
// Document ID (generated or not)
String _id = response.getId();
System.out.println(_id);
// Version (if it's the first time you index this document, you will get: 1)
long _version = response.getVersion();
System.out.println(_version);
// isCreated() is true if the document is a new one, false if it has been updated
boolean created = response.isCreated();
System.out.println(created);
client.close();
}catch (Exception ex){
ex.printStackTrace();
}
}
}
In the Java logs I can see that there is a connection with 127.0.0.1:9300. But after the "prepare index" command I do not see any error and nothing is printed(I have some system out commands). In the ElasticSearch logs is also nothing relative. When I create an index with the Rest API I can see this in the logs.
Ok, as #Val mentioned I forgot to print the errors. The problem was that JSONObject is not the format that ElasticSearch wants. Map and HashMap are acceptable.

Problem retrieving the earthquake JSON results?

Greeting! After I removed hardcoded JSON data and moved to request data from the URL. I am having an exception error. The code is pretty much the same as the final official git but I am getting the errors.
The code that I am extracting data from JSON is:
private static final String USGS_REQUEST_URL =
"http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=5&limit=10";
//
public static List<Earthquake> extractFeaturesfromJson(String earthquakeJSON) {
/*if the json is null then return earlu*/
if (TextUtils.isEmpty(earthquakeJSON)) {
return null;
}
// Create an empty ArrayList that we can start adding earthquakes to
List<Earthquake> earthquakes = new ArrayList<>();
// Try to parse the JsonResponseString. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception so the app doesn't crash, and print the error message to the logs.
try {
// create an object form jsonString
JSONObject root = new JSONObject(earthquakeJSON);
JSONArray features = root.getJSONArray("features");
for (int i = 0; i < features.length(); i++) {
// Get a single earthquake at position i within the list of earthquakes
JSONObject currentEarthquake = features.getJSONObject(i);
// For a given earthquake, extract the JSONObject associated with the
// key called "properties", which represents a list of all properties
// for that earthquake.
JSONObject properties = currentEarthquake.getJSONObject("properties");
double mag = properties.getDouble("mag");
String location = properties.getString("place");
long time = properties.getLong("time");
//extract the value of key url
String url = properties.getString("url");
//create new object with magnitude, location ane time and url from json response
Earthquake earthquake = new Earthquake(mag, location, time, url);
earthquakes.add(earthquake);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing the earthquake JSON results", e);
}
// Return the list of earthquakes
return earthquakes;
}
The logcat shows:
09-26 14:49:23.628 2551-2584/com.example.android.quakereport E/com.example.android.quakereport.QueryUtils: Problem retrieving the earthquake JSON results.
The json data from your url is not formatted correctly. Compare what you are receiving from the url to the hardcoded data.
This method runs on the main UI thread after the background work has been
completed. This method receives as input, the return value from the doInBackground() method.
First we clear out the adapter, to get rid of earthquake data from a previous
query to USGS.
Then we update the adapter with the new list of earthquakes, which will trigger the ListView to re-populate its list items. But made mistake on populating data to adapter.
#Override
protected void onPostExecute(List<Earthquake> data) {
//clear the adapter of previdous earthquake data
mAdapter.clear();
if (data != null && data.isEmpty()) { //====?????shourld be !data.isEmpty())
mAdapter.addAll(data);
}
}
The real problem was onPostExecute method to populate data in mainthread after do in background method.
If you're taking the Udacity android course and encountering this error for the quakereport/DidUfeelIt app then change the URL and try with some other URL your problem will be solved.
Eg:- The URL provided by during the course was
"http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2012-01-01&endtime=2012-12-01&minmagnitude=6"
Then I was getting the same error that is "problem parsing the JSON"
So I tried different URL:
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson
And it worked..!!
Always try to get the latest URL's from the USGS website during the course.
Change your request URL to USGS_REQUEST_URL="https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=6&limit=10"
The difference is in the use of https instead of http.
According to the API doc of the USGS website this website now uses the HyperText Transfer Protocol Secure (https)
https://earthquake.usgs.gov/fdsnws/event/1/
Use Online Json Validator.
http://jsonlint.com/
they will validate if the json has problems.

How to follow Single Responsibility principle in my HttpClient executor?

I am using RestTemplate as my HttpClient to execute URL and the server will return back a json string as the response. Customer will call this library by passing DataKey object which has userId in it.
Using the given userId, I will find out what are the machines that I can hit to get the data and then store those machines in a LinkedList, so that I can execute them sequentially.
After that I will check whether the first hostname is in block list or not. If it is not there in the block list, then I will make a URL with the first hostname in the list and execute it and if the response is successful then return back the response. But let's say if that first hostname is in the block list, then I will try to get the second hostname in the list and make the url and execute it, so basically, first find the hostname which is not in block list before making the URL.
Now, let's say if we selected first hostname which was not in the block list and executed the URL and somehow server was down or not responding, then I will execute the second hostname in the list and keep doing this until you get a successful response. But make sure they were not in the block list as well so we need to follow above point.
If all servers are down or in block list, then I can simply log and return the error that service is unavailable.
Below is my DataClient class which will be called by customer and they will pass DataKey object to getData method.
public class DataClient implements Client {
private RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
private ExecutorService service = Executors.newFixedThreadPool(15);
public Future<DataResponse> getData(DataKey key) {
DataExecutorTask task = new DataExecutorTask(key, restTemplate);
Future<DataResponse> future = service.submit(task);
return future;
}
}
Below is my DataExecutorTask class:
public class DataExecutorTask implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public DataExecutorTask(DataKey key, RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.key = key;
}
#Override
public DataResponse call() {
DataResponse dataResponse = null;
ResponseEntity<String> response = null;
MappingsHolder mappings = ShardMappings.getMappings(key.getTypeOfFlow());
// given a userId, find all the hostnames
// it can also have four hostname or one hostname or six hostname as well in the list
List<String> hostnames = mappings.getListOfHostnames(key.getUserId());
for (String hostname : hostnames) {
// If host name is null or host name is in local block list, skip sending request to this host
if (ClientUtils.isEmpty(hostname) || ShardMappings.isBlockHost(hostname)) {
continue;
}
try {
String url = generateURL(hostname);
response = restTemplate.exchange(url, HttpMethod.GET, key.getEntity(), String.class);
if (response.getStatusCode() == HttpStatus.NO_CONTENT) {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.NO_CONTENT,
DataStatusEnum.SUCCESS);
} else {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.OK,
DataStatusEnum.SUCCESS);
}
break;
// below codes are duplicated looks like
} catch (HttpClientErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (HttpServerErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (RestClientException ex) {
// if it comes here, then it means some of the servers are down so adding it into block list
ShardMappings.blockHost(hostname);
}
}
if (ClientUtils.isEmpty(hostnames)) {
dataResponse = new DataResponse(null, DataErrorEnum.PERT_ERROR, DataStatusEnum.ERROR);
} else if (response == null) { // either all the servers are down or all the servers were in block list
dataResponse = new DataResponse(null, DataErrorEnum.SERVICE_UNAVAILABLE, DataStatusEnum.ERROR);
}
return dataResponse;
}
}
My block list keeps-on getting updated from another background thread every 1 minute. If any server is down and not responding, then I need to block that server by using this -
ShardMappings.blockHost(hostname);
And to check whether any server is in block list or not, I use this -
ShardMappings.isBlockHost(hostname);
I am returning SERVICE_UNAVAILABLE if servers are down or in block list,on the basis of response == null check, not sure whether it's a right approach or not.
I am not following Single Responsibility Principle here I guess at all.
Can anyone provide an example what is the best way to use SRP principle here.
After thinking a lot, I was able to extract hosts class like given below but not sure what is the best way to use this in my above DataExecutorTask class.
public class Hosts {
private final LinkedList<String> hostsnames = new LinkedList<String>();
public Hosts(final List<String> hosts) {
checkNotNull(hosts, "hosts cannot be null");
this.hostsnames.addAll(hosts);
}
public Optional<String> getNextAvailableHostname() {
while (!hostsnames.isEmpty()) {
String firstHostname = hostsnames.removeFirst();
if (!ClientUtils.isEmpty(firstHostname) && !ShardMappings.isBlockHost(firstHostname)) {
return Optional.of(firstHostname);
}
}
return Optional.absent();
}
public boolean isEmpty() {
return hostsnames.isEmpty();
}
}
Your concern is valid. First, let's see what the original data executor do:
First, it is getting list of hostnames
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request.
If not valid: skip.
Else continue.
Generate the URL based on hostname
Send the request
Translate the request response to domain response
Handle exceptions
If the hostnames is empty, generate an empty response
Return response
Now, what can we do to follow SRP? As I can see, we can group those operations into some groups. What I can see is, these operations can be split into:
HostnameValidator: checks whether the hostname is valid to send request
--------------
HostnameRequestSender: Generate the URL
Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
That is, one approach to de-couple your operations and to follow SRP. There is also other approach, for example to simplify your operations:
First, it is getting list of hostnames
If the hostnames is empty, generate an empty response
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
Next, it loops through every valid hostnames that do the following things:
Send the request
Translate the request response to domain response
Handle exceptions
Return response
Then it can also be split into:
HostnameValidator: checks whether the hostname is valid to send request
--------------
ValidHostnameData: Getting list of hostnames
Loops through every hostnames that do the following things:
Checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
--------------
HostnameRequestSender: Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
Of course there are also other way to do it. And I leave the implementation details blank because there is many way to implement it.

Problems Creating New Initiative with Rally JAVA Rest API 2.0

I am using the following code snippet to try to create an Initiative in Rally (the values I am using for _ref I obtained while debugging).
public void createInitiative() {
CreateRequest request = null;
CreateResponse response = null;
JsonObject jo = new JsonObject();
String wsRef = "/workspace/11785043049";
String prjRef = "/project/11785043139";
jo.addProperty("Workspace", wsRef);
jo.addProperty("Project", prjRef);
jo.addProperty("Name","api_create_initiative_01");
jo.addProperty("Owner","/user/17085226946");
jo.addProperty("_ref", "/portfolioItem/initiative");
jo.addProperty("_type", "portfolioItem/initiative");
request = new CreateRequest("Initiative", jo);
try {
response = api.create(request);
JsonElement je = response.getObject();
System.out.println(je.getAsString());
} catch (IOException e) {
e.printStackTrace();
}
}
The response is :
{"CreateResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Not authorized to perform action: Invalid key"], "Warnings": ["It is no longer necessary to append \".js\" to WSAPI resources."]}}
I have no idea which "key" is invalid.
Also, not sure if I should be using "Initiative" or "PortfolioItem/Initiative" both fail
The security token needed to be append to the url as specified in the docs when you find them.
I had cannibalized code from the rallyapi test program for api setup and the security token was not appending when performing a create. Also my code snippet above had to be changed to create("PortfolioInitiative",jo) and the property "_type" was not needed

Categories

Resources