OData4j 0.7 Exception while retrieving workitems - java

I am trying to retrieve workitems from TFS Server using OData4j 0.7 in Java.
Here is my code:
public List<TFSWorkItem> getWorkItems(final String projectName)
{
final List<TFSWorkItem> tfsWorkItems = new ArrayList<TFSWorkItem>();
String filter = String.format("Project eq '%s'", projectName);
Enumerable<OEntity> workItems = consumer.getEntities("WorkItems").filter(filter).execute();
for (OEntity workitem : workItems)
{
System.out.println(workitem.getProperty("Title", String.class));
}
}
When I run this code I get a
Exception in thread "main" java.lang.IllegalArgumentException: Illegal datetime format 2013-03-15T14:22:08.077+05:30
at org.odata4j.internal.InternalUtil.parseDateTimeFromXml(InternalUtil.java:96)
On further debugging the code I found that OData4j when trying to map the retrieved date from TFS server finds it incompatible .
Date retrieved from TFS :
2013-03-15T14:22:08.077+05:30
Date expected by OData4j :
2013-03-15T14:22:08.077
Is there a way where I can avoid this?
Updated
For anybody who is facing the same issue.
I have modified my code to :
final String fields = "Id,Project,Title";
Enumerable<OEntity> workItems = consumer.getEntities("WorkItems").filter(filter).select(fields.toString()).execute();
for (OEntity workitem : workItems)
{
System.out.println("Id : " + workitem.getProperty("Id").getValue());
System.out.println("Project : "+workitem.getProperty("Project").getValue());
System.out.println("Title : "+workitem.getProperty("Title").getValue());
}
Since I need only these fields to process I have given a select query to select "Id","Project" and "Title" instead of fetching all fields.
This is a temporary fix unless I find a better solution.

I think I figured this out. Check out this post: OData4J exception
Basically, it boils down to setting the value of an Edm.DateTime column in C# code using DateTime.Now. The OData Producer should be using DateTime.UtcNow.
DateTime.Now includes local time zone information. Microsoft's code sees the local time zone info in the DateTime structure and sends back the Edm.DataTime field formatted as an Edm.DateTimeOffset string. The DateTime.UtcNow property does not include any time zone information, so it is correctly formatted as an Edm.DateTime string when it is sent back to the OData Consumer.
I suspect this might be a bug in Microsoft's WCF Data Services stack or their Entity Framework.

Related

getting “input value must be specified” error while sending graphQL query through java

I am trying to get some data by using graphQL. code should be in following format ,but while debugging ,i got error as following:
[{"message":"\"input\" value must be specified","category":"graphql-input","locations":[{"line":1,"column":10}]}]
Basically I want data in following format in java .
query { customer { id addresses { id firstname lastname street city region { region_code region region_id } postcode country_id telephone } } }
query i wrote in java is as following :
return q -> q.customerId()
.id()
.firstname()
.lastname()
.street()
.city()
.region(getCustomerAddressRegionQuery())
.postcode()
.countryId()
.telephone();
so what java query should i write in order to get the output. attached image of error here as well
error says:
"input" value must be specified","category":"graphql-input","locations":[{"line":1,"column":10}
The problem is not in returning the value from java, the problem is with the graphql query you are performing. The query expects an input named 'input' but you are not giving it. What does your GraphQL query look like?
If you are testing it through postman i think you should enter input data, e.g in body.

Insert data in a partition of CouchDB from java

I'm using cloudant API for CouchDB in JAVA. I've created a partitioned database from Java but now i don't know how to create a partition and insert my json in this one.
final String dbName = "cinema";
CloudantClient client = ClientBuilder.url(new URL(url)).username(username).password(passw).build();
System.out.println("Server version: " + client.serverVersion());
Database db = CreatePartitioned.createPartitionedIfNotExists(client, dbName);
db.createIndex("movies"); //doesn't work
I have this error:
Exception in thread "main" com.cloudant.client.org.lightcouch.CouchDbException: 400 Bad Request at http://127.0.0.1:5984/movielens/_index. Error: bad_request. Reason: invalid UTF-8 JSON.
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:597)
at com.cloudant.client.org.lightcouch.CouchDbClient.executeToInputStream(CouchDbClient.java:648)
at com.cloudant.client.api.Database.createIndex(Database.java:391)
at provaCouch.Prova_CouchDB.main(Prova_CouchDB.java:20)
I have to create 3 partition and on the net there are poor information. Does anybody know how to fix this problem?
It looks like you're not sending the correct argument to createIndex().
See the docstring for the createIndex method, and the API doc it references. You will probably want to use the index builder instead (com.cloudant.client.api.query.JsonIndex.Builder).

Java & MongoDB query for date range

Before I start, I have already searched around for an answer to this issue and the best answer I could come up with is this question
I have one difference though. I have a table that maintains a history of many documents. Therefore I need to query on an ID as well as the date range. Here is what my query currently looks like in Java
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("id", id);
searchQuery.put("dateModified", BasicDBObjectBuilder.start("$gte", fromDate).add("$lte", toDate).get());
DBCursor cursor = table.find(searchQuery);
This returns no results. The MongoQuery that is generated by this block of code looks like this:
db.history.find({ "id" : 12345 , "dateModified" : { "$gte" : { "$date" : "2015-01-19T00:00:00.000Z"} , "$lte" : { "$date" : "2015-01-25T00:00:00.000Z"}}});
When I manually type this into MongoDB command line, this also returns no results. I currently have one record in the database for testing purposes that looks like this:
{
"id" : NumberLong(12345),
"dateModified" : ISODate("2015-01-21T19:42:28.044Z")
}
This object should clearly match the query, yet nothing is returning, any ideas?
EDIT: So it turns out that the string generated by the query object doesn't match the ISODate object in the database. I'd like to clarify that fromDate and toDate are both java.util.Date objects. I'm still not sure how to solve this though.
I figured out the issue. I don't understand the cause, but the issue is with the BasicDBObjectBuilder not using the Date object correctly. I switched to QueryBuilder and built the exact same query and it returned results.
fromDate must be of the type Date not the String representation. An ISODate in the MongoDB storage Engine is not equal to the String representation of the same date and so they do not match.

Converting (.net) BsonDocument string into a (java) DBObject

In a publishing flow I need to insert a DBObject into a mongo db collection using Java.
I receive the object as a String, and this has been passed to me from a .NET application that used article.ToBsonDocument().ToJson() on a POCO.
On my side of the flow, in Java, I tried just using BasicDBObject doc = (BasicDBObject) JSON.parse(content); but I get a com.mongo.util.JSONParseException on a Date:
"CreationDate" : ISODate("2013-03-18T08:50:53Z")
I can change how the content is generated in C#, and I can change how to write to the DB in java, my only constraint is that it must be passed as a string between the two systems.
Any suggestions?
EDIT Thanks to the tip from #Jim Dagg below, some googling for ISODate and BsonDocument turned out this gem. Changing the c# code to use
article.ToBsonDocument().ToJson(new JsonWriterSettings{OutputMode = JsonOutputMode.Strict});
fixed it.
The ISODate constructor call is what's causing the issue. From an issue on the MongoDB JIRA:
The parser accepts these two date formats: seconds ->
"yyyy-MM-dd'T'HH:mm:ss'Z'" or seconds.milleseconds ->
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" Just add seconds to your $date value
and the aggregation command should work. Here's the JSON doc that I
had success with: { "aggregate" : "test", pipeline : [ {$match : {
date : { $date : "2012-05-01T12:30:00Z" } } } ] }
If you remove the ISODate constructor and simply render your date as (for example) "2013-03-18T08:50:53Z", you should be in business.

Database timestamps not matching

I have an action in struts2 that will query the database for an object and then copy it with a few changes. Then, it needs to retrieve the new objectID from the copy and create a file called objectID.txt.
Here is relevant the code:
Action Class:
ObjectVO objectVOcopy = objectService.searchObjects(objectId);
//Set the ID to 0 so a new row is added, instead of the current one being updated
objectVOcopy.setObjectId(0);
Date today = new Date();
Timestamp currentTime = new Timestamp(today.getTime());
objectVOcopy.setTimeStamp(currentTime);
//Add copy to database
objectService.addObject(objectVOcopy);
//Get the copy object's ID from the database
int newObjectId = objectService.findObjectId(currentTime);
File inboxFile = new File(parentDirectory.getParent()+"\\folder1\\folder2\\"+newObjectId+".txt");
ObjectDAO
//Retrieve identifying ID of copy object from database
List<ObjectVO> object = getHibernateTemplate().find("from ObjectVO where timeStamp = ?", currentTime);
return object.get(0).getObjectId();
The problem is that more often than not, the ObjectDAO search method will not return anything. When debugging I've noticed that the Timestamp currentTime passed to it is usually about 1-2ms off the value in the database. I have worked around this bug changing the hibernate query to search for objects with a timestamp within 3ms of the one passed, but I'm not sure where this discrepancy is coming from. I'm not recalculating the currentTime; I'm using the same one to retrieve from the database as I am to write to the database. I'm also worried that when I deploy this to another server the discrepancy might be greater. Other than the objectID, this is the only unique identifier so I need to use it to get the copy object.
Does anyone know why this is occuring and is there a better work around than just searching through a range? I'm using Microsoft SQL Server 2008 R2 btw.
Thanks.
Precision in SQL Server's DATETIME data type does not precisely match what you can generate in other languages. SQL Server rounds to the nearest 0.003 - this is why you can say:
DECLARE #d DATETIME = '20120821 23:59:59.997';
SELECT #d;
Result:
2012-08-21 23:59:59.997
Then try:
DECLARE #d DATETIME = '20120821 23:59:59.999';
SELECT #d;
Result:
2012-08-22 00:00:00.000
Since you are using SQL Server 2008 R2, you should make sure to use the DATETIME2 data type instead of DATETIME.
That said, #RedFilter makes a good point - why are you relying on the time stamp when you can use the generated ID instead?
This feels wrong.
Other than the objectID, this is the only unique identifier
Databases have the concept of a unique identifier for a reason. You should really use that to retrieve an instance of your object.
You can use the get method on the Hibernate session and take advantage of the session and second level caches as well.
With your approach you execute a query everytime you retrieve your object.

Categories

Resources