Power App Custom Connector: Cannot call CRM function RetrieveRolePrivilegesRole - dynamics-crm

My swagger JSON for the custom connector looks like below:
"/roles({roleid})/Microsoft.Dynamics.CRM.RetrieveRolePrivilegesRole": {
"post": {
"responses": {
"200": {
"description": "Success Operation"
}
},
"parameters": [
{
"name": "roleid",
"in": "path",
"type": "string",
"required": true
}
],
"operationId": "_POST_RetrieveRolePrivilegesRole",
"description": "Retrieve Role Privileges",
"summary": "Retrieve Role Privileges"
}
},
When I create a custom connector with this and test the call, I am getting following error:
{
"error": {
"code": "0x0",
"message": "Resource not found for the segment 'Microsoft.Dynamics.CRM.RetrieveRolePrivilegesRole'",
"innererror": {
"message": "Resource not found for the segment 'Microsoft.Dynamics.CRM.RetrieveRolePrivilegesRole'",
"type": "Microsoft.Crm.CrmHttpException",
"stacktrace": " at Microsoft.Crm.Extensibility.ODataV4.Routing.CrmODataRoutingConvention.ThrowUnresolvedSegmentException(ODataPath odataPath)\r\n at Microsoft.Crm.Extensibility.ODataV4.Routing.CrmODataRoutingConvention.SelectActionImplementation(ODataPath odataPath, HttpControllerContext controllerContext, ILookup`2 actionMap)\r\n at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func`1 func, IEnumerable`1 additionalCustomProperties)\r\n at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func`1 func)\r\n at System.Web.OData.Routing.ODataActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
}
}

Related

400 Error in People API [people.updateContact ]

400 Error in People API [people.updateContact]
I'm need updateContact field locations of user in g-suite
i get 400 error "Resource name "people/{xxxxxxx}" is not a valid contact person resource."
request
{
"resourceName": "people/xxxxxxxxxxx",
"etag": "xxxxxxxxxxxxxx",
"locations": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "xxxxxxxxxxxxxxxx"
}
},
"value": "TestA",
"current": true
},
{
"metadata": {
"source": {
"type": "PROFILE",
"id": "xxxxxxxxxxxxxxxxx"
}
},
"value": "TestB"
}
]
}
response
{
"error": {
"code": 400,
"message": "Resource name \"people/{xxxxxxx}\" is not a valid contact person resource.",
"status": "INVALID_ARGUMENT"
}
}
Answer:
The error "Resource name \"people/{xxxxxxx}\" is not a valid contact person resource." appears because the resource name you are providing in your request is not a valid contact person resource.
Fix:
Replace people/{xxxxxxx} with a valid resource. You can obtain these using people.listDirectoryPeople endpoint.

Spring boot swagger multipart with json content and attachment

I've a requirement to upload any file content using Swagger-3 along with some metadata information as a JSON within a single request. Therefore I configured following into my swagger:
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"metadata": {
"$ref": "#/components/schemas/Attachment"
},
"file": {
"type": "string",
"format":"binary",
"description": "Actual File Attachment"
}
}
}
}
},
"description": "The Attachment record / entry be created",
"required": true
}
It translates to following when I build the controller object:
#ApiOperation(value = "Upload attachments to a existing Ticket", nickname = "uploadAttachment", notes = "", response = Attachment.class, responseContainer = "List", tags={ "changeRequest", })
#RequestMapping(value = "/changeRequest/attachment/{id}",
produces = { "application/json" },
consumes = { "multipart/form-data" },
method = RequestMethod.POST)
public ResponseEntity<List<Attachment>> uploadAttachment(#ApiParam(value = "Identifier of the Change Request",required=true) #PathVariable("id") String id,#ApiParam(value = "Application ID invoking the call" ,required=true) #RequestHeader(value="X-App-Id", required=true) String xAppId,#NotNull #ApiParam(value = "To track unique transaction across multiple systems for audit trail", required = true) #Valid #RequestParam(value = "X-Transaction-Id", required = true) String xTransactionId,#ApiParam(value = "Authorization header" ) #RequestHeader(value="authorization", required=false) String authorization,#ApiParam(value = "", defaultValue="null") #RequestParam(value="metadata", required=false) Attachment metadata, #ApiParam(value = "file detail") #Valid #RequestPart("file") MultipartFile file) {
ResponseEntity<List<Attachment>> responseEntity = new ResponseEntity<>(HttpStatus.OK);
responseEntity.getBody().add(metadata);
return responseEntity;
}
Following is the Attachment schema definition:
"Attachment": {
"type": "object",
"description": "Attachment Metadata definition",
"properties": {
"description": {
"type": "string",
"description": "A narrative text describing the content of the attachment"
},
"href": {
"type": "string",
"description": "Reference of the attachment"
},
"id": {
"type": "string",
"description": "Unique identifier of the attachment"
},
"mimeType": {
"type": "string",
"description": "The mime type of the document as defined in RFC 2045 and RFC 2046 specifications."
},
"name": {
"type": "string",
"description": "The name of the file"
},
"path": {
"type": "string",
"description": "The path of the attached file"
},
"size": {
"type": "integer",
"description": "The size of the file (sizeUnit if present indicates the unit, otherwise kilobytes is the default)."
},
"sizeUnit": {
"type": "integer",
"description": "The unit size for expressing the size of the file (MB,kB...)"
},
"url": {
"type": "string",
"description": "Uniform Resource Locator, is a web page address (a subset of URI)"
},
"validFor": {
"$ref": "#/components/schemas/TimePeriod",
"description": "Period of validity of the attachment"
},
"#type": {
"type": "string",
"description": "The class type of the actual resource (for type extension)."
},
"#schemaLocation": {
"type": "string",
"description": "A link to the schema describing a resource (for type extension)."
},
"#baseType": {
"type": "string",
"description": "The base type for use in polymorphic collections"
}
}
}
In the example above, Attachment metadata is what I am trying to pass as part of the SOAP API test. However I keep getting following error:
Mon Oct 12 17:06:28 IST 2020:DEBUG:<< "{"timestamp":"2020-10-12T11:36:28.371Z","status":500,"error":"Internal Server Error","message":"Failed to convert value of type 'java.lang.String' to required type 'com.bell.na.nt.change.swagger.model.Attachment'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.bell.na.nt.change.swagger.model.Attachment': no matching editors or conversion strategy found","path":"/changeManagement/api/v1/changeRequest/attachment/1234"}"
Why is the string not being converted and mapped to the JSON object. Not sure I am missing anything. Following is what my json looks like.
{"#baseType": "string", "#schemaLocation": "string", "#type": "string", "description": "string", "href": "string", "id": "string", "mimeType": "string", "name": "string", "path": "string", "size": 0, "sizeUnit": 0, "url": "string", "validFor": { "endDateTime": "2020-10-11T19:06:40.586Z", "startDateTime": "2020-10-11T19:06:40.586Z"}}
Postman Request
Turns out I had to add the a converter for converting the string representation of the JSON to desired Swagger generated Model object something like:
#Component
public class StringToAttachmentObjectConverter implements Converter<String, Attachment> {
Logger logger = LoggerFactory.getLogger(StringToAttachmentObjectConverter.class);
#Autowired
private ObjectMapper objectMapper;
DocumentContext docContext = null;
#Override
public Attachment convert(String source) {
try {
String sourceString = JsonPath.using(NetsUtilityJSONDatumUtils.jsonPathConfig).parse(source).jsonString();
return objectMapper.readValue(sourceString, Attachment.class);
} catch (JsonParseException e) {
logger.error("Error While converting the String: \n" + source, e);
} catch (JsonMappingException e) {
logger.error("Error While converting the String: \n" + source, e);
} catch (IOException e) {
logger.error("Error While converting the String: \n" + source, e);
}
return null;
}
}
Not sure if there is any better way or if I am defying any best practice(s) but this did the trick for me.

What is the Json response we should send to microsoft botFramework to route my response to telegram channel

I am sending below response to the service url provided by botFramework request https://telegram.botframework.com/v3/conversations/-263387177/activities/
My intent is that using sendMessage method of telegram I am able to route a text to the telegram channel via microsoft botframework
The http post which I am sending is as below
{
"type": "message",
"locale": "en-Us",
"chat_id":-263387177,
"channelID":"telegram",
"from": {
"id": "GTSFIBot",
"name": "sapeops"
},
"text":"hi , Greetings!",
"replyToId": "1505813737353",
"recipient": {
"id": "DirectLineClient"
},
"conversation": {
"isGroup": true,
"id": "-263387177",
"name": "sapeops group"
},
"channelData": {
"method": "sendMessage",
"parameters": {
"chat_id": -263387177,
"parse_mode": "HTML",
"text": "<B>Greetings! How are you doing?</B>"
},
"chat": {
"id": -263387177,
"title": "sapeops group",
"type": "group",
"all_members_are_administrators": true
}
}
}
I get 502 bad gateway response and a below JSON.
{
"error": {
"code": "ServiceError",
"message": "Telegram API returned a result code indicating non-success"
}
}

How to parse json with mixed child objects using Sprint Rest Template

I have a json response which looks like below
{
"resourceType": "Topic",
"metadata": {
"lastUpdated": "2016-12-15T14:51:33.490-06:00"
},
"entry": [
{
"resource": {
"resourceType": "Outcome",
"issue": [
{
"response": "error",
"code": "exception"
},
{
"response": "success",
"code": "informational"
},
{
"response": "success",
"code": "informational"
}
]
}
},
{
"resource": {
"resourceType": "Data",
"id": "80",
"subject": {
"reference": "dataFor/80"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
},
{
"resource": {
"resourceType": "Data",
"id": "90",
"subject": {
"reference": "dataFor/90"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
}
]
}
Data and Outcome Class extends Resource.
I am using Spring RestTemplate.getForObject(url, someClass). I get below error
has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not read JSON: Unrecognized field "response" (Class com.model.Resource), not marked as ignorable
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#77a3e67a;
I understand that the json is not getting parsed to the child class of Resource. I want to do something like RestTemplate.getForObject(url, someClass) but this is not supported by java generics (wildcard). Please help
You'll want to use jackson to deserialize to a dynamic type, using resourceType as the field to indicate the actual type. Add these to your Resource class.
#JsonTypeInfo(property = "resourceType", use = Id.NAME)
#JsonSubTypes({ #Type(Data.class),
#Type(Outcome.class)
})
Here is a unit test that will prove out the behavior.
#Test
public void deserializeJsonFromResourceIntoData () throws IOException {
Data data = (Data) new ObjectMapper().readValue("{" +
" \"resourceType\": \"Data\"," +
" \"id\": \"80\"," +
" \"subject\": {" +
" \"reference\": \"dataFor/80\"" +
" }," +
" \"created\": \"2016-06-23T04:29:00\"," +
" \"status\": \"current\"" +
" }", Resource.class);
assertEquals(Integer.valueOf(80), data.getId());
assertEquals("dataFor/80", data.getSubject().getReference());
}
As for the cast, I've done it here just to demonstrate that it works, however, to be truly polymorphic, you probably want to have Resource contain all the behavior you need, and then everything is just a Resource.

How to add http status to all responses dto(data transfer object)?

I've been developing a Spring Boot REST API. I've done so many things so far except my problem. I'm using springfox swagger UI for documentation, and I separated models and dtos for better structure.
I have a base dto model:
public class BaseDto {
private int code;
private boolean success;
public BaseDto() {
this.code = HttpStatus.OK.value();
this.success = HttpStatus.OK.is2xxSuccessful();
}
}
And of course I'm using this class by extending it like:
#ApiModel("User")
public class UserDto extends BaseDto {
private String email;
private String username;
// stuffs
}
If I do user requests when I use this structure, I get:
{
code: 200,
success: true,
email: "",
username: ""
}
and so on... That's fine, but in other dtos, like post model, I have List of UserDto and it's showed in that form. In every object, "code" and "success" fields are written; however, this is not I want to.
The goal that I want to achieve is only once "code" and "success" are written in the response JSON body not all returning list objects.
To clarify more this is Post Dto Model and returns like this:
{
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"id": "string",
"likes": [
{
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"deviceType": "string",
"email": "string",
"fbAccessToken": "string",
"fbId": "string",
"followers": [
{}
],
"followings": [
{}
],
"id": "string",
"profileImage": "string",
"success": true,
"token": "string",
"udid": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"username": "string",
"version": 0
}
],
"pictures": [
"string"
],
"postedBy": {
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"deviceType": "string",
"email": "string",
"fbAccessToken": "string",
"fbId": "string",
"followers": [
{}
],
"followings": [
{}
],
"id": "string",
"profileImage": "string",
"success": true,
"token": "string",
"udid": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"username": "string",
"version": 0
},
"success": true,
"text": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"userId": "string",
"userIds": [
"string"
],
"version": 0
}
You can see at Post Dto model where User Dto is used, code and success fields are added redundant.
I don't know most probably I got wrong approach. Perhaps, I should use adding global HTTP status response to all returning DTOs.
Can anyone help?
You can have an AppUtil class were you can create your response and set HttpStatus. In your AppUtil class write a method like so :
public static ResponseEntity<ResponseEnvelope> successResponse(Object data,
int messageCode, String message) {
ResponseEnvelope envelope = new ResponseEnvelope(data, true, message,
messageCode);
ResponseEntity<ResponseEnvelope> responseEntity = new ResponseEntity<>(
envelope, HttpStatus.OK);
return responseEntity;
}
In the successResponse method you can set your data object in the ResponseEnvelope which along with the HttpStatus will be sent in the ResponseEntity that you want to return.
Check out my previous answer here

Resources