How to push array into Anypoint Monitoring custom metrics? - mule

I need to push an JSON array information into custom dashboard table.
[
{
api_name: "abc_api",
owner: "avish"
},
{
api_name: "xyz_api",
owner: "avesh"
},
etc...
]
I need to push the info into a table with 2 column like API_NAME and API_OWNER.
Please let me know if this can be possible with 'anypoint custom metric' connector or do we have any option in mulesoft ?

Values for measurements have to be numerical. It doesn't seem that the data that you want to push is compatible with custom metrics.

Related

How to use a connected/embedded object's groups attribute to authenticate the parent record in AWS AppSync (Amplify)

Background
In a project I am working on, we are using AWS as the cloud provider and Amplify with AppSync GraphQL to help rapidly build the back end. AppSync in Amplify defaults to having a DynamoDB database so that is what we are using with it.
We are using data-level security so users can only see records they are meant to see in a shared database.
There is a hierarchy whereby a Project object can contain many other objects and we need to ensure that anyone who is authorised to view the Project, can also view everything it contains.
The Problem
To do this, it was assumed that we could have an Asset object with a projectId attribute and project connection to populate the project details on reading the record. The Project table/object contains a groups attribute which we use dynamic group security in the #auth directive.
here's an example of the schema:
type Project
#model
#auth(rules: [
{ allow: groups, groupsField: "groups" }
])
{
id: ID!
title: String!
reference: String
clientId: ID!
client: Organisation!
#connection(fields: ["clientId"])
modifiedById: ID
changeComment: String
groups: [String!]
}
type Asset
#model
#key(name: "byProjectId", fields: ["projectId"])
{
id: ID!
name: String!
projectId: ID!
project: Project!
#connection(fields: ["projectId"])
completedAt: AWSDateTime
}
It is simplified so does not make a lot of sense as written. Ideally, we would use the #auth directive to specify the field for the Asset type as well like this
#auth( allow: groups, groupsField: "project.groups" )
We have also attempted to do it manually with a custom resolver written in Velocity (.vtl) which turned out to be very much the same thing:
#set( $allowedGroups = $util.defaultIfNull($item.project.groups, []) )
#set( $userGroups = $util.defaultIfNull($ctx.identity.claims.get("cognito:groups"), []) )
#foreach( $userGroup in $userGroups )
#if( $util.isList($allowedGroups) )
#if( $allowedGroups.contains($userGroup) )
#set( $isLocalDynamicGroupAuthorized = true )
#end
#end
#if( $util.isString($allowedGroups) )
#if( $allowedGroups == $userGroup )
#set( $isLocalDynamicGroupAuthorized = true )
#end
#end
#end
After checking it, I found at the time this resolver is run, the project field is null which leads me to think it has not been joined in yet so can't be used as originally planned.
The Answer?
Is there a way to do this or a more suitable alternative? My concern is that the obvious solution of having all objects having their own groups attribute which contains the parent project's user group name could get very unwieldy as there are upwards of 10k assets to a project and more than just assets to consider.
Am I wrestling with my urge to normalise the data since this is a NoSQL db and we should just duplicate the values and handle that in the code?
Would a User Permission Matrix table be more sensible and would it be easy enough to build into AppSync with Amplify?
Any hints as to how to do this or implement a more suitable solution would be very much appreciated.

Mobx-state-tree create form with types.identifier field on model

I've started using mobx-state-tree recently and I have a practical question.
I have a model that has a types.identifier field, this is the database id of the resource and when I query for existing stuff it gets populated.
When I am creating a new instance, though, following the example that Michel has on egghead, I need to pass an initial id to my MyModel.create() on initial state, however, this ID will only be known once I post the creation to the API and get the resulting created resource.
I have searched around for a simple crud example using mobx-state-tree but couldn't find one (suggestions?).
What is the best practice here? Should I do a `MyModel.create({ id: 'foobar' }) and weed it out when I post to the API (and update the instance once I get the response from the API)?
This is a limitation of mobx-state-tree's current design. Identifiers are immutable.
One strategy I've seen to get around this issue is to store your persistence layer's id in a separate field from your types.identifier field. You would then use a library like uuid to generate the types.identifier value:
import { v4 } from "node-uuid"
const Box = types
.model("Box", {
id: types.identifier,
name: "hal",
x: 0,
y: 0
})
const box = Box.create({ 'hal', 10, 10, id: v4() })

Zapier lazy load input fields choices

I'm building a Zapier app for a platform that have dynamic fields. I have an API that returns the list of fields for one of my resource (for example) :
[
{ name: "First Name", key: "first_name", type: "String" },
{ name: "Civility", key: "civility", type: "Multiple" }
]
I build my action's inputFields based on this API :
create: {
[...],
operation: {
inputFields: [
fetchFields()
],
[...]
},
}
The API returns type that are list of values (i.e : Civility), but to get these values I have to make another API call.
For now, what I have done is in my fetchFields function, each time I encounter a type: "Multiple", I do another API call to get the possible values and set it as choices in my input field. However this is expensive and the page on Zapier takes too much time to display the fields.
I tried to use the z.dehydrate feature provided by Zapier but it doesn't work for input choices.
I can't use a dynamic dropdown here as I can't pass the key of the field possible value I'm looking for. For example, to get back the possible values for Civility, I'll need to pass the civility key to my API.
What are the options in this case?
David here, from the Zapier Platform team.
Thanks for writing in! I think what you're doing is possible, but I'm also not 100% that I understand what you're asking.
You can have multiple API calls in the function (which it sounds like you are). In the end, the function should return an array of Field objects (as descried here).
The key thing you might not be aware of is that subsequent steps have access to a partially-filled bundle.inputData, so you can have a first function that gets field options and allows a user to select something, then a second function that runs and pulls in fields based on that choice.
Otherwise, I think a function that does 2 api calls (one to fetch the field types and one to turn them into Zapier field objects) is the best bet.
If this didn't answer your question, feel free to email partners#zapier.com or join the slack org (linked at the bottom of the readme) and we'll try to solve it there.

Square Connect API: Retrieving all items within a category

I have been reading over the Square Connect API and messing around with the catalog portion.
I am unable to find how to retrieve all items and their data associated with a particular category. Can someone please point me in the right direction.
I thought it was the
BatchRetrieveCatalogObjects endpoint
I was using the category ID but it was only returning the catalog's data. I need each of the IDs of the items to retrieve their individual data.
I was looking to propagate a list of all the items and their data in one request in JSON.
JSON data to be passed to endpoint:
data = {
"object_ids": [
"category id"
],
"include_related_objects": True
}
My connection to the API:
category_item_endpoint = self.connection.post('/v2/catalog/batch-retrieve', data)
I am using python3 and the requests library.
In order to list items in a category I found it easiest to use the /v2/catalog/search endpoint. Simply follow the documentation on what parameters are accepted. Below are the search parameters that I used to list items by category id.
let sParams: JSON = [
"object_types": [
"ITEM"
],
"include_related_objects": true,
"include_deleted_objects": false,
"query": [
"exact_query": [
"attribute_name": "category_id",
"attribute_value": id
]
],
"limit": 1000
]
You'd probably have the most luck listing your entire catalog GET /v2/catalog/list and then applying filtering (in this case specific catagory_ids ) after you get the data. Based on the documentation doing what you desire doesn't seem possible with an endpoint/query combitionation.

Storing custom application configurations on cumulocity

Is there a way to store custom application configurations on the Cumulocity backend through the c8y.sdk? I would like to store a JSON with configuration information specific to an application created using the the smart app toolkit.
You can save settings at the tenant by using c8ySettings,
BUT you have a limitation of 256 characters per value.
I'm struggling with the same problem of storing larger plugin configurations without any success.
I asked about this from cumulocity support and they said it is possible to store custom JSON under managedobjects because at the moment they dont support storing JSON to database otherwise.
So you will need "create" or "admin" rights to inventory to be able to create new managedobject. You can store values like this:
var userSettings = {
type: 'userDashboardSettings',
yourSetting: somesetting,
id: settingsId
};
c8yInventory.save(userSettings).then(function(){
//do something
});
then you can search this newly created managedobject like this:
c8yInventory.list({
type: 'userDashboardSettings',
owner: id,
pageSize: 2
}).then(function (settings) { //do something }
So this way I was for example able to save user specific settings.
To find user dashboard settings do GET to: https://yourdomain.com/inventory/managedObjects/?type=userDashboardSettings&owner=IDHERE
To Delete managedObject do DELETE to: https://yourdomain.com/inventory/managedObjects/IDHERE
To see all managedObjects do GET: https://yourdomain.com/inventory/managedObjects
Type and user are important, this is how you find the managedobject.