Get the list of all products and their custom attributes

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.

 

0 8 442
8 REPLIES 8

@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.