Get the list of all products and their custom attributes for a given apikey in the proxy.
I have an app and attached to multiple products. Each product has custom attrbiutes. I have a requirement to get the list of all custom attributes which are related to all products for an app/apikey.
I tried AccessEntity
<EntityType value="apiproduct"/>
<EntityIdentifier ref="request.header.apikey" type="consumerkey"/>
This gives just first product linked to an app.
Cheers,
Suresh.
@dchiesa1 , Any suggestions?
@anilsr , any suggestions
Hello Suresh,
You will need to use AccessEntity
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessEntity async="false" continueOnError="false" enabled="true" name="Access-App-Info">
<DisplayName>Access App Info</DisplayName>
<FaultRules/>
<Properties/>
<EntityIdentifier ref="apikey" type="consumerkey"/>
<EntityType value="app"/>
</AccessEntity>
Then lookup the products using XMLtoJSON Policy
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLToJSON async="false" continueOnError="true" enabled="true" name="Products-to-JSON">
<DisplayName>Products to JSON</DisplayName>
<FaultRules/>
<Properties/>
<OutputVariable>apiCredential</OutputVariable>
<Source>AccessEntity.ChildNodes.Access-App-Info.App.Credentials</Source>
<Options>
<TreatAsArray>
<Path>Credentials/Credential</Path>
<Path>Credentials/Credential/ApiProducts/ApiProduct</Path>
</TreatAsArray>
</Options>
</XMLToJSON>
This should give you list of all the products...
You can also get it through javascript code by doing this
var credentials = apiCredential.Credentials.Credential;
var apiProductsList = [];
try {
if (appStatus == "approved") {
credentials.forEach(function(credential) {
if (credential.ConsumerKey == apikey
&& (credential.ExpiresAt == -1 || credential.ExpiresAt > now)
&& credential.Status == "approved") {
credential.ApiProducts.ApiProduct.forEach(function(apiProduct){
if (apiProduct.Status == "approved") {
apiProductsList.push(apiProduct.Name);
}
});
}
});
}
if (apiProductsList.length > 0) {
context.setVariable("isValidApiKey", "true");
}
} catch (err) {
print(err);
}
You can lookup for custom attributes attached to product object in JavaScript as well..
Hi,
Thank you so much for your reply.
I tried the xml->json, and observed it doesn't have customattributes information in the product section.
below the credentials extract
{
"Credentials": {
"Credential": [{
"Attributes": {},
"ConsumerKey": "aasdsada",
"ConsumerSecret": "fdgsfdgfsd",
"ExpiresAt": "-1",
"IssuedAt": "1663117723840",
"ApiProducts": {
"ApiProduct": [{
"Name": "SB-DevProduct",
"Status": "approved"
}, {
"Name": "DEv2",
"Status": "approved"
}, {
"Name": "dev3",
"Status": "approved"
}, {
"Name": "dev4",
"Status": "approved"
}]
},
"Scopes": {},
"Status": "approved"
}]
}
}
Try this..
<TreatAsArray>
<Path>Credentials/Credential</Path>
<Path>Credentials/Credential/ApiProducts/ApiProduct</Path><Path>Credentials/Credential/ApiProducts/ApiProduct/Attributes/Attribute</Path>
</TreatAsArray>
Thank you so much for your reply.
Same response even after Attributes/Attribute path in array. I am just wondering is it because "App" entity type never loads attributes and proxies linked to it?
below my xml->json
<XMLToJSON async="false" continueOnError="true" enabled="true" name="Products-to-JSON">
<DisplayName>Products to JSON</DisplayName>
<FaultRules/>
<Properties/>
<OutputVariable>apiCredential</OutputVariable>
<Source>AccessEntity.ChildNodes.Access-App-Info.App.Credentials</Source>
<Options>
<TreatAsArray>
<Path>Credentials/Credential</Path>
<Path>Credentials/Credential/ApiProducts/ApiProduct</Path>
<Path>Credentials/Credential/ApiProducts/ApiProduct/Attributes/Attribute</Path>
</TreatAsArray>
</Options>
</XMLToJSON>
Ok this might not be possible declaratively through policy, another option would be to create a Proxy, which accepts product name, and then returns the custom attributes, you can call this proxy from javascript and pass productname as param..
var apiProductsList = [];
try {
if (appStatus == "approved") {
credentials.forEach(function(credential) {
if (credential.ConsumerKey == apikey
&& (credential.ExpiresAt == -1 || credential.ExpiresAt > now)
&& credential.Status == "approved") {
credential.ApiProducts.ApiProduct.forEach(function(apiProduct){
if (apiProduct.Status == "approved") {
//Make a call to proxy which returns an products attributes...
}
});
}
});
}
if (apiProductsList.length > 0) {
context.setVariable("isValidApiKey", "true");
}
} catch (err) {
print(err);
}
Thank you Manoj. Not an ideal solution, i will give a try if you think that is the best possible solution given the current APIGEE capability.