How to get custom extension attributes with microsoft graph api - java

I'm trying to get user details with microsoft-graph
I'm looking for a custom extension element in my response, such as "extension_3a4189d71ad149c6ab5e65ac45bd6add_MyAttribute1"
when I retrieve the response with String, I can see all the elements.
final ResponseEntity<String> response = restTemplate.exchange("http://graph.windows.net/tenant.com/me?api-version=1.6, HttpMethod.GET, new HttpEntity(headers),String.class);
But when I retrieve the response with com.microsoft.graph.models.extensions.User I can't see the extention anymore.
final ResponseEntity<User> response = restTemplate.exchange("http://graph.windows.net/tenant.com/me?api-version=1.6, HttpMethod.GET, new HttpEntity(headers),User.class);
How can I retrieve the custom extension in more elegant way than getting in String object and look for elements one by one?

because the extension attributes are specific to your tenant, that means its non standard, no out of the box "object class" in the sdk would contain it since it has the app id appended to it. extension_appid_attribname.
so you would have to handle it yourself. you can try to extend the user class and add a method to read or deserialize/map the json return from the graph api similar to what Hury suggested, or something to that effect. there won't likely be an out of the box solution for this.
there are also json libraries out there that may help you deserialize to a dynamic object of some sort, if you really didn't want to map the object manually.
Update:
I dug into this a bit further. I don't think its in extensions.extension however, I did find that in the java sdk you can access it . Here's the documentation: https://github.com/microsoftgraph/msgraph-sdk-java/wiki/Working-with-Open-Types
You would do something like
String ext =
user
.additionalDataManager()
.get("extension_2lkj3l12jl3j2kj3_yourproperty")
.getAsString();
Give that a try
Hopefully that helps.

Please use api
https://graph.microsoft.com/beta/users instead of https://graph.microsoft.com/v1.0/users api https://graph.microsoft.com/beta/users will return all data with custom data of users.

Related

How to retrieve AWS Textract response JSON using the Java SDK

I am using AWS Textract to OCR images and create a searchable PDF as outlined in this AWS blog post.
The basic request code looks like this:
AmazonTextractClientBuilder builder = AmazonTextractClientBuilder.standard();
DetectDocumentTextRequest request = new DetectDocumentTextRequest()
.withDocument(new Document()
.withBytes(imageBytes));
DetectDocumentTextResult result = client.detectDocumentText(request);
List<Block> blocks = result.getBlocks()
This works out great however I would also like to write out and keep the original response JSON that contains all the information on what was detected where etc.
Is there a way to get to the response JSON using the JAVA SDK?
AWS doesn't return the response JSON to you in raw form. The assumption may have been that it wouldn't be required once it has been converted to a DetectDocumentTextResult object.
You are able to convert the DetectDocumentTextResult object to JSON (example) which should provide identical values. Note that the variable names will not be identical (e.g.: DocumentMetadata vs documentMetadata) but the values of those variables will be the same.

How to deal with API call that can return different JSON data structure depending on result data

I am trying to write code using RestTemplate exchange to query an API that returns song info. The problem is that the data looks like this when data is found but
{"search":[{"song_id":"4R9o2J","song_title":"xxxx", ...}]
but like this if the song is not found
{"search":{"error":"no result"}}
When reading valid data my result object looks like this
Data
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(JsonInclude.Include.NON_NULL)
public class SongSearch {
List<SongInfo> search;
}
The problem is that when the data is valid, there is no property to contain the array of info... it is the contents of the "search": [{....}] so I can't create a property that will get ignored when it is not found even though the not found message has an error property. In other words, the search property can contain an array OR a single property depending on whether data was found or not.
My exchange call looks like this:
ResponseEntity<SongSearch> res = restTemplate.exchange(url, HttpMethod.GET, entity, SongSearch.class);
I've been able to write code that catches the deserialization exception in the not found case but the exception does not contain the actual error message from the API, which I'd want to return. I am currently able to hack it by making a call again with a different object to capture the error but that seems insane. There MUST BE a better way to do this. Just to be clear, this is not an actual error status returned from the client... the data is just different but it breaks the deserialization.
Anyone have suggestions?

Getting JSON data for any site

I am trying to build my new App and I need some data for it.
so I was wondering if I can get JSON data (or query link or any source file) of any site for now and for future.
I need to get data from this site:
https://study.ekb.eg/ - https://www.ekb.eg/
Note: https://www.ekb.eg/ is the main source data for https://study.ekb.eg/
Thanks
The site needs to be specifically programmed to return JSON data for you. Regular, normal sites are not like this. They generally just return HTML
So the site owner would need to set up an API for you to consume

Can I transform a JSON-LD to a Java object?

EDIT: I changed my mind. I would find a way to generate the Java class and load the JSON as an object of that class.
I just discovered that exists a variant of JSON called JSON-LD.
It seems to me a more structured way of defining JSON, that reminds me XML with an associated schema, like XSD.
Can I create a Java class from JSON-LD, load it at runtime and use it to convert JSON-LD to an instantiation of that class?
I read the documentation of both the implementations but I found nothing about it. Maybe I read them bad?
Doing a Google search brought me to a library that will decode the JSON-LD into an "undefined" Object.
// Open a valid json(-ld) input file
InputStream inputStream = new FileInputStream("input.json");
// Read the file into an Object (The type of this object will be a List, Map, String, Boolean,
// Number or null depending on the root object in the file).
Object jsonObject = JsonUtils.fromInputStream(inputStream);
// Create a context JSON map containing prefixes and definitions
Map context = new HashMap();
// Customise context...
// Create an instance of JsonLdOptions with the standard JSON-LD options
JsonLdOptions options = new JsonLdOptions();
// Customise options...
// Call whichever JSONLD function you want! (e.g. compact)
Object compact = JsonLdProcessor.compact(jsonObject, context, options);
// Print out the result (or don't, it's your call!)
System.out.println(JsonUtils.toPrettyString(compact));
https://github.com/jsonld-java/jsonld-java
Apparently, it can take it from just a string as well, as if reading it from a file or some other source. How you access the contents of the object, I can't tell. The documentation seems to be moderately decent, though.
It seems to be an active project, as the last commit was only 4 days ago and has 30 contributors. The license is BSD 3-Clause, if that makes any difference to you.
I'm not in any way associate with this project. I'm not an author nor have I made any pull requests. It's just something I found.
Good luck and I hope this helped!
see this page: JSON-LD Module for Jackson

Jersey Post request - How to perform a file upload with an unknown number of additional parameters?

I asked something like this previously, but upon re-reading my original post, it was not easy to understand what I was really asking. I have the following situation. We have (or at least I'm trying to get working) a custom file upload procedure that will take in the file, a set number of 'known' metadata values (and they will always be there), as well as potentially an unknown number of additional metadata values. The service that exists currently uses the Jersey framework (1.16)
I currently have both client and server code that handles dealing with the file upload portion and the known metadata values (server code below)
#POST
#Path("asset/{obfuscatedValue0}/")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public UUID uploadBlob(#PathParam("obfuscatedValue0") Integer obfuscatedValue0,
#FormDataParam("obfuscatedValue1") String obfuscatedValue1,
#FormDataParam("obfuscatedValue2") String obfuscatedValue2,
#FormDataParam("obfuscatedValue3") String obfuscatedValue3,
#FormDataParam("obfuscatedValue4") String obfuscatedValue4,
#FormDataParam("obfuscatedValue5") String obfuscatedValue5,
#FormDataParam("file") InputStream uploadedInputStream) {
.....
}
...and excerpt of client code:
Builder requestBuilder = _storageService
.path("asset")
.path(obfuscatedValue0.toString())
.type(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.APPLICATION_JSON);
FormDataMultiPart part = new FormDataMultiPart()
.field("file", is, MediaType.TEXT_PLAIN_TYPE) // 'is' is an inputstream from earlier in code.
.field("obfuscatedValue1", obfuscatedValue1)
.field("obfuscatedValue2", obfuscatedValue2)
.field("obfuscatedValue3", obfuscatedValue3)
.field("obfuscatedValue4", obfuscatedValue4)
.field("obfuscatedValue5", obfuscatedValue5);
storedAsset = requestBuilder.post(UUID.class, part);
However, I need to pass a map of additional parameters that will have an unknown number of values/names. From what I've seen, there is no easy way to do this using the FormDataParam annotation like my previous example.
Based upon various internet searches related to Jersey file uploads, I've attempted to convert it to use MultivaluedMap with the content type set to "application/x-www-form-urlencoded" so it resembles this:
#POST
#Path("asset/{value}/")
#Consumes("application/x-www-form-urlencoded")
public UUID uploadBlob(#PathParam(value), MultivaluedMap<String,String> formParams) {
....
}
It's my understanding that MultivaluedMap is intended to obtain a general map of form parameters (and as such, cannot play nicely together in the same method bearing #FormDataParam annotations.) If I can pass all this information from the Client inside some sort of map, I think I can figure out how to handle parsing the map to grab and 'doMagic()' on the data to get what I want done; I don't think I'll have a problem there.
What I AM fairly confused about is how to format the request client-side code when using this second method within the jersey framework. Can anyone provide some guidance for the situation, or some suggestions on how to proceed? I'm considering trying the solution proposed here and developing a custom xml adapter to deal with this situation, and sending xml instead of multipart-form-data but I'm still confused how this would interact with the InputStream value that will need to be passed. It appears the examples with MultivaluedMap that I've seen only deal with String data.

Categories