Creating Group categories - D2L Valence - rest

I am attempting to dynamically create a group category with in a course using the following service:
[/d2l/api/lp/(version)/(orgUnitId)/groupcategories/ \[POST\]][1]
The following is the GroupData (Group.GroupData in Create form) JSON block that I am sending to this service:
{
"Name": "New Group Category",
"Description": {
"Content": "",
"Type": "HTML"
},
"EnrollmentStyle": 0,
"EnrollmentQuantity": null,
"AutoEnroll": false,
"RandomizeEnrollments": false,
"NumberOfGroups": 5,
"MaxUsersPerGroup": null
}
I am making the call with the user context of a administrative "Utility" account. I have 2 test courses, both of which I have confirmed I am able create the category through the web interface using this utility account.
My problem is I am having mixed results depending on the course that I try to create the category in. In one course the course returns 200-OK, in the other it returns 403-Forbidden.
Here are the (simplified) requests :
Call 1
/d2l/api/lp/1.4/350110/groupcategories/
Result: 403-Forbidden
Call 2
/d2l/api/lp/1.4/19988/groupcategories/
Result: 200-OK
The only difference is the OrgUnitID. Version, JSON, and user context are all the same, yet I'm getting 2 different results. I have tried with several other courses and again, I have success in some but not all; always receiving a 403 as the error.
After some investigation, I believe I have found 2 distinct differences between courses that are successful and those that return 403.
Courses created just before April 2012 are successful, anything afterwards fail
Courses with a 5 digit Org Unit ID are successful, anything with 6 digits seems to fail.
So my thoughts are we either applied a patch late march / early April of 2012 which somehow changed how courses are flagged on creation, OR somehow only 5 digits (or less?) Org IDs are being accepted by the service.
I'm hoping someone could provide some insight or verify they have no issue with 6+ digit OUIDs and group category creation.

Further reviewing the documentation on API Responses - Disposition and error handling I realized that there are 3 possible cases for a 403 response:
Response body contains Timestamp out of range
Response body contains Invalid Token
application or calling user context does not have the permissions required for the attempted action
Given this, I took a closer look at the response header and realized the issue was actually #2 "Invalid Token", not #3 as I was assuming.
Investigating my code further it seems the user defined SHA256 function I was using was producing an incorrect HASH/Signature when the data being hashed was exactly 55 characters long (yes I realize how crazy this sounds). The temporary work around is to pad my OrgIDs with leading zeros, so my request would actually look something similar too:
/d2l/api/lp/1.4/00350110/groupcategories/
Thankfully, this seems to work, and is acceptable for the immediate future. Long term solution will be to replace my SHA256 function with something more reliable.
I am using Colfusion 7MX for my development, which does not have a native SHA256 Hash function, hence the use of the user defined function.

Related

IBM Maximo REST service POST not setting attributes on MBO

I have tried to create a record of my customized object through REST service in IBM Maximo.
The problem is that I created the record but I can't assign values to the attributes.
Next I will show what I did and what happened:
I have an Object Structure called oxidato that represents my customized object.
I did a POST using POSTMAN to this URL:
http://hostname:port/maximo/oslc/os/oxidato?lean=1
In the body section this is the JSON I was trying to send:
{
"attribute1":"205",
"attribute2":"206"
}
The record was created but none of the attributes was filled.
In my opinion, the REST service received the POST but canĀ“t read the body.
What am I missing? I add an image of the POSTMAN as example:
EDIT1: I update the POST in order to use the newest API RES (Thanks Dex!)
EDIT2: I add an image of the header
I have found that Maximo will often ignore incoming attributes that aren't in the Maximo namespace (http://www.ibm.com/maximo). You could go through the trouble of setting up your VALOR1 and VALOR2 attributes to be in that namespace, but it's easier to just tell OSLC to ignore namespaces. You do that by setting the "lean" parameter to "1".
In your case, go to the "Params" tab and add an entry with a name of "lean". Give it a value of "1" and then send your POST again. You should see "?lean=1" appear at the end of the POST URL along the top there, but your body content should remain unchanged.
EDIT:
On the other hand, it looks like (based on your URL) that you aren't actually using the newer JSON/OSLC REST API; It looks like you are using the older REST services. This IBM page gives you a lot of information on the newer JSON REST API, including the correct URLs for it: https://developer.ibm.com/static/site-id/155/maximodev/restguide/Maximo_Nextgen_REST_API.html.
You should change your URL to /maximo/oslc/os/oxidato to use the newer API that naturally supports JSON and the lean parameter described above. This does required Maximo 7.6 to use though.
EDIT 2:
The attributes are often oddly case sensitive, requiring lowercase. Your example in your question of "attribute1" and "attribute2" are properly lowercase, but your screenshot shows uppercase attribute names. Try changing them to "valor1" and "valor2". Also, these are persistent attributes, right?
The response code received back (e.g. 200 - OK) and the response body will detail the record that was created.
I think you are correct in that the body of the post request is being ignored. Provided there are no required fields on the custom MBO your POST is probably creating an empty record with the next value in the sequence for the key field but you should see that in the response.
The following POST should create a record with values provided for attribute1 and attribute2 and provide a response with the record's identifier so that you can look it up in Maximo and show the values that were stored for attribute1 and attribute2:
http://hostname:port/maximo/rest/os/oxidato/?_format=json&_compact=1&attribute1=205&attribute2=206
Response: 200 OK
Reponse Body:
{ "CreateOXIDATOResponse": {
"rsStart": 0,
"rsCount": 1,
"rsTotal": 1,
"OXIDATOSet": {
"OXIDATO": {
"rowstamp": "[0 0 0 0 0 -43 127 13]",
"ATTRIBUTE1": "205",
"ATTRIBUTE2": "206",
"OXIDATOID": 13
}
} } }
You may also want to turn on debug logging for the REST interface in System Configuration -> Platform Configuration -> Logging for additional detail on what's happening in the log file.

Issues with google REST api: enum keys returns spurious values

Im trying to write some code to rotate service account keys for integration testing. To this end I have a function that gets all the keys for a test account using the REST api. This involves sending a GET request to
https://iam.googleapis.com/v1/projects/" + projectName + "/serviceAccounts/" + accountEmail + "/keys"
The result(s) of this are a JSON string with an array of Map that have
keyName (project/account/keyId)
validAfterTime
validBeforeTime
keyAlgorithm
the 'before' and 'after' times are Zulu values that seem to indicate valid times for said key.
This is all well and good.. except.. that with every call I seem to get 2 or more entries that are either expired or not valid yet, have a 2 day valid span and don't appear in the google console. Trying to delete one of these returns a
"code": 400, "message": "Request contains an invalid argument."
What are these entries? Why are they showing up in this list?
Edit -
if someone from google happens to wander by this post - there is a doc bug on this page. The URL for 'listing service keys' should be a GET request and not a POST as it currently shows.

REST: Update resource with unknown (server-generated) value

I have a resource foo with the following structure:
GET /foo/1 returns:
{
"id": 1,
"server-key": "abcdef",
"status": "expired"
}
Status can either be active or expired. If it is expired I want the server to generate a new one.
Normally I'd issue PUT/PATCH foo/1 with the new key, but client doesn't know the key-generation algorithm.
I could also do a POST foo/1/server-key with no body, but that feels strange (I know this isn't very scientific reason though).
Any good ideas/patterns?
In case when you've got expired entity just make POST call on /foo without any parameters and server should return new entity (and HTTP response code should be 201):
{
"id": 2,
"server-key": "xyz",
"status": "active"
}
If some resourece is expired it is unconvinient to make it active again by PUT/PATCH request.
The approach I would adopt is to set a null value to server-key and let the server deal with it, but I do that because it's a consistent behavior in my APIs for the server to fill missing values with defaults.
Other than that, a simple POST to the URI as suggested in the other answer is adequate.
I think that you should use a PUT/PATCH method in your case to ask for generate a token if expired. Generally it's not really RESTful to put an action name within the resource path ;-)
I would see something like that:
Get the element: GET /foo/1
If the status is expired, ask for a new server key to be generated: POST /foo/1. In this case, this method will be used to execute an action to reinitialize the key on the server side
Using the method PUT corresponds to update the complete representation with a new one provided by the client. With the method PATCH, you will do a partial update of the representation.
Here is a link that could give you some hints about the way to design a Web API (RESTful service): https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry

Facebook Graph API event-id/comments?since=2014-02-01&until=2014-02-10 , Date filter has no effect

I am trying to bring comments made on a particular event by targeting this URL: https://graph.facebook.com/1466384840257158/comments
I am passing the user_access_token
I have two comments at present on this event made on the same
day(2014-03-29)
Now I try to pass a date which should bring an empty data result/object
like this: https://graph.facebook.com/1466384840257158/comments?since=2011-01-01&until=2014-01-10
This request has no effect, it still shows me the two comment made
on the 29th
I have tried the same kind of date range on my user-id/feed and it
gave me an empty data object.
Finally i tried event-id/feed (before trying date filter) and it
gave me the following error
.
{
"error": {
"message": "An unexpected error has occurred. Please retry your request later.",
"type": "OAuthException",
"code": 2
}
}
Could you please guide me about date filter on that particular query (point4) or if you have any other idea to use date filter on comments made for an event.
Comments use Cursor-based Pagination, so you cannot use since or until on the comments endpoint (these parameters would work f.ex. for the feed endpoint).
To get the comments in a time range you have to fetch all comments from NOW to the start of the time range, f.ex. with https://graph.facebook.com/1466384840257158/comments?filter=stream&limit=1000+paging (the filter=stream will order the result with the timestamp).
USING SINCE UNTIL FOR COMMENTS on GROUP
If you want to use since and until for comments, it is not possible directly for a group. So, First you can apply it for status(feed) and then get the comments for that feed.
This works for me:
{group_id}/?fields=feed.since(08/25/2016).until(08/31/2016){from,comments{from,message}}
Why don't you try first to filter by notifications?... notifications allows you to add parameters like since. For example (using Facebook pages):
https://graph.facebook.com/PAGEID?fields=notifications.since(2015-3-31 00:00:00).limit(250).include_read(true)&{id,created_time,updated_time,unread,object,link}&access_token=ACCESSTOKEN
Once you got the json data, loop through data, get the ID and send a second request but this time using the PAGEID_POSTID edge. Something like this:
https://graph.facebook.com/PAGEID_POSTID/comments?fields=id,from{name,id},message,can_remove,created_time&limit=1000
Voahla!... there's no need to read every comment!...
Note 1: A Page access token is required, along with the manage_pages permission
Note 2: Use the parameter/field include_read to get all the notifications, even the already readed
Note 3: In the second request, use the parameter/field "filter=stream" to order the posts and get the comments made in the name of your page
Note 4: Don't forget to control the asynchronicity once you loop!
Note 5: Notifications duplicate posts, use an array to avoid to read more than one time the postUse the parameter/field include_read to get all the notifications, even the already readed
I do not know if it's too late. But, Yeah it works in the graph api version 3.3.
for example: if you wanna get comments on a post of a Facebook page you can do it like this:
You have to use page Access-token
The get Graph Request : post_id/comments?since=some_date

Search Facebook events and pagination (Graph API)

I am requesting this page to get the events with the keyword
"conference":https://graph.facebook.com/search?q=conference&type=event
This works fine.
The problem is the pagination returned:
"paging": {
"previous":"https://graph.facebook.com/search?q=conference&type=event&limit=25&since=2010-12-18T17%3A00%3A00%2B0000",
"next":"https://graph.facebook.com/search?q=conference&type=event&limit=25&until=2010-11-04T16%3A29%3A59%2B0000"
}
It seems to have more events with "conference", but requesting these 2 pagination URLS returns no data.
It's weird because it's the same for any requested keyword, and the pagination URLs returned by the Facebook API seems to always returns empty data.
Does anyone know what's the issue?
Thanks
I encountered similar confusion with a query against places. The "next" URL behaved exactly as you described it.
I could query location information using a url like this:
https://graph.facebook.com/search?access_token=INSERT_TOKEN&type=place&center=55.8660,-4.2715&distance=150&limit=10
And got back JSON with the first 10 places plus the following fragment which suggests the existence of paging params:
"paging": {
"next": "https://graph.facebook.com/search?access_token=INSERT_TOKEN&type=place&center=55.8660\u00252C-4.2715&distance=150&limit=10&offset=10"
Hitting that URL doesn't work. But I did figure out a combination of limit and offset params that gave me effective paging.
limit=10 & offset not defined => first 10 results
limit=20 & offset=10 => next 10 results
limit=30 & offset=20 => next 10 results
limit=40 & offset=30 => last 8 results (can stop here because less than 10 back)
limit=50 & offset=40 => confirmation that there are no more results
I realise that I've got "limit" and "offset" rather than the "limit" and "until" params that you get, but, hopefully you could apply the same technique i.e. keep incrementing the limit and inc the date/time to that of your last result?
I think this is a standard practice in Facebook Graph API. I think if your request resulted to a non empty JSON, they will always give you the next paging, even though it might be empty.
I am however not 100% sure, because Facebook Graph API does not seem to be very well documented... (for example they said we can modify this pagination thing but did not explain clearly how to do it).
Seems facebook has changed it recently.
Here's the fix:
For a datetime returned in next and previous as
"2011-01-18T08\u00253A42\u00253A35\u00252B0000",
replace all occurrences of "\u0025" with "%" and it should work fine.
If you notice the facebook's datetime format, it is
2011-01-18T08:42:35+0000
(date accepted by strtotime C function)