Parse ODATA URL to read ID value before preparing entityset - java

I'm new to ODATA. The examples given in https://olingo.apache.org builds the entityset first and then out of it, it fetches one entity based on the ID passed in the URL. What i need is how to read the entity id from the URL and then build the entity.
Ex: In the request /car.srv/Cars(5), read 5 in the Servlet and then build the entity.
Can someone help me how to do it in Java?

Related

Spring ReactiveCrudRepository doesn't support PUT? TransientDataAccessException

I'm using Spring to build a simple Web app. At the front end I have a REST api, which has a PUT method like this: /api/v1/apple/{id}
When the call comes in to this endpoint, the body is deserialised to an Apple.
In the spec for PUT it says: "The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI."
So if apple 21 exists in the DB (and is therefore reachable at /api/v1/apple/21), it should be replaced with the one in the request.
But if it doesn't, a new one should be created, as per the apple in the request, with primary key 21 and URI /api/v1/apple/21.
The problem is that the ReactiveCrudRepository seems not to support this.
According to the release notes, since spring-data r2dbc 1.0.0, if you call save() and the row doesn't exist in the database, it throws a TransientDataAccessException. I see the following:
Failed to updated table [apples]. Row with Id [21] does not exist.
org.springframework.dao.TransientDataAccessResourceException: Failed to updated table [apples]. Row with Id [21] does not exist.
at app//org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$doUpdate$14(R2dbcEntityTemplate.java:707)
.....
So if I supply an ID for my new Apple, I can't create it - at least not using ReactiveCrudRepository. If I remove the ID from the POJO first, it will create it, but with an assigned ID - in other words calling PUT /api/v1/apple/21 will result in creation of an apple, but with some other id (not 21).
What am I missing here? There appear to be no alternatives to the save() method which behave the way I need.

spring boot mongo db collection get document before a know document id

I have developed a Rest api using spring boot with mongo db. So far I am able to add documents and retrieve them using the api.
But I need to implement a path in which the client can provide a document id and I need to retrieve the 10 records that were entered before the provided document id.
I am not able to write the query for this request.
I tried the following code but it didn't work.
FindIterable<Document> iterable= collection.find(lt("_id", new ObjectId("5f986445bf87483ade34a3fe"))).sort(descending("_id")).limit(10);
5f986445bf87483ade34a3fe is the id of a known document in the collection.

Partial JSON update on DynamoDB

I have a simple dynamo table that consists of cookies and attributes:
customer
cookie
attribute_1
attribute_2
...
attribute_n
Right now, these attributes are variable and need to be updated upon receiving a partial JSON through and endpoint.
I made my mind into using the new JSON type field in DynamoDB (since that's our main datastore choice), and I intend to reshape the table into:
customer
cookie
attributes
Where attributes is just a JSON document.
Main issues:
I have no way of knowing which attributes are going to be added
I have no way ok knowing which items already exist (save from making an extra query)
I'd like to avoid a super complex code to do this
Main goal:
In an ideal world, there should be some way of having or not an item in dynamo and passing the primary key along with some JSON and then having the DB partially update the existing JSON.
So far I've seen this kind of code:
DynamoDB dynamo = new DynamoDB(new AmazonDynamoDBClient(...));
Table table = dynamo.getTable("people");
table.updateItem(
new UpdateItemSpec()
.withPrimaryKey("person_id", 123)
.withUpdateExpression("SET document.current_city = :city")
.withValueMap(new ValueMap().withString(":city", "Seattle")));
But I'd like to avoid making an extra query (to know if I need to create or update) and constructing all the update expressions.
Is there a way to do this?
Here is a full example just in case:
1) Receive the following JSON in the API:
{"name": "John"}
Expected dynamo attribute:
attributes={"name": "John"}
2) Receive the following JSON in the API:
{"age": 12}
Expected dynamo attribute:
attributes={"name": "John", "age": 12}
And so on. The primary key is constructed from the request cookie / customer.
My hopes for this existing comes from the fact that dynamo supports the smart updateItem (which I'm currently using) that allows to specify only some attributes to update or create an item.

Unboundid not returning requested LDAP attributes. Why?

I have written a program that reads a webservice, retrieving user data, and then is supposed to push that data to ActiveDirectory, thus updating the user's title, address, phone numbers, etc.
The problem is that when I perform the search using the Unboundid Connection class the requested attributes are not returned. Below is the search code:
SearchResult result = connection.search( properties.getProperty("ldap.search.baseDN"),
SearchScope.SUB, "(cn=" + userId + ")",
"personalTitle", "department", "company", "manager", "telephoneNumber",
"streetAddress", "I", "st", "postalCode", "c", "pager", "mobile",
"fax", "cn");
The above code locates the desired user and the cn attribute is returned as expected, but the other attributes all fail to return. If I connect to AD using JXplorer using the same connection credentials, I'm able to see all the desired attributes exist, but are simply not being returned.
I have tried substituting SearchRequest.ALL_OPERATIONAL_ATTRIBUTES, SearchRequest.ALL_USER_ATTRIBUTES and SearchRequest.REQUEST_ATTRS_DEFAULT rather than listing the fields explicitly, but with no success.
I have also looked at the 'Schema' object returned from 'connection.getSchema()' and can see that personalTitle should exist:
connection.getSchema().getAttributeType("personalTitle")
The above code returns:
1.2.840.113556.1.2.615 NAME 'personalTitle' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE
So maybe this is a user permission issue? Has anyone experienced this and know how to resolve it?
Thanks,
Mike
LDAP search result entries only include attributes that actually have values, so the behavior you are seeing from the UnboundID LDAP SDK is appropriate and correct. Even if you explicitly request a particular attribute, that attribute will only be included in the entry if it has one or more values.
I think that you're confused by JXplorer because it's reading the schema to determine what attributes could possibly be included in the entry based on its object classes and is showing them to you so that you can set values for those attributes in the editor. But that doesn't mean that the entry returned by the server actually includes any information about those attributes.
To verify this, you can use the ldap-debugger tool provided with the LDAP SDK to see the actual LDAP communication that occurs. Just run a command like:
tools/ldap-debugger --hostname {directory-server-address} \
--port {directory-server-port} --listenPort {listen-port}
This will create a very simple LDAP proxy server that decodes all requests and responses that pass through it. To use it, simply point JXplorer at the specified listen-port. You will see that when JXplorer retrieves the entry, the entry returned by the server will only contain attributes that actually have values.
If you want to figure out what all the possible attributes are that you can include in a given entry, then use the LDAPConnection.getSchema method to retrieve the server schema, then Schema.getObjectClass for each of the object classes in the target entry, and finally use the ObjectClassDefinition.getRequiredAttributes and ObjectClassDefinition.getOptionalAttributes methods to see what attribute types must and may be used in entries with that object class.

Retrieving the UUID from Apache Solr after a commit

I am using Solrj to add new documents to a Solr instance. In my document schema the id is a UUID (solr.UUIDField). Each time a document is created the id is filled with the unique id, which is exactly what I want. Sometimes it's necessary in my application that I can retrieve this unique id to add it as a field value when inserting another document. So my question is, how can I retrieve this generated uuid from solr after adding a document?
Solrj returns me this UpdateResponse object after commiting, but I don't know how to get the new uuid out of it.
I am adding a document like this
CommonsHttpSolrServer server = new CommonsHttpSolrServer(MY_SERVER_URL);
SolrInputDocument doc = new SolrInputDocument();
// [...] multiple addField calls
server.add(doc);
UpdateResponse ur = server.commit();
AFAIK you aren't going to ever get a UUID from an add or a commit. When you do an add or commit, the update request handler gives you back query time and status, but not much else (assuming it is successful). You can actually see what is in the HTTP response by running a manual add/commit like so:
http://localhost:8983/solr/update?stream.body=<add><doc><field name="id">test</field><field name="title">test title</field></doc></add>
http://localhost:8983/solr/update?stream.body=<commit/>
If you run those queries in a web browser, they will submit a test document and commit it, respectively. You will then be able to see what information is available to SolrJ (not much).
You could write your own (modified) update handler in Java, but that seems like a ton of work. You could also enable the "timestamp" field in your Solr schema so you can query solr by last modified date and find the items you just committed.
Both of those methods would be major hacks, though. Your best bet is to figure out a unique ID for your documents before you submit them to Solr, then use that unique ID to retrieve them. Using a generated UUID is more of a "fire and forget about this" method. Since you don't want to forget, you will need to generate your own UUID.
Since you're using Java, it should be dead simple to do with UUID, using some code like this:
CommonsHttpSolrServer server = new CommonsHttpSolrServer(MY_SERVER_URL);
SolrInputDocument doc = new SolrInputDocument();
UUID uuid = UUID.randomUUID();
doc.addField("id", uuid.toString());
// [...] multiple addField calls
server.add(doc);
UpdateResponse ur = server.commit();

Categories