-1

I am suppose to be getting this JSON string but I am stuck with this error FATAL_ERROR System.TypeException: Invalid conversion from runtime type List to Map

This is the JSON String:

{
    "system_overview": [
        {
            "attributes": {
                "type": "System_Overview__c",
                "url": "/services/data/v43.0/sobjects/System_Overview__c/a006F000032qqS6QAI"
            },
            "Max_API__c": 15000,
            "Requested_API__c": 4228,
            "Usable_API__c": 10772,
            "Total_Storage__c": 5,
            "Used_Storage__c": 0,
            "Remaining_Storage__c": 5,
            "Id": "a006F000032qqS6QAI"
        }
    ],
    "packages": [
        {
            "attributes": {
                "type": "Installed_Package__c",
                "url": "/services/data/v43.0/sobjects/Installed_Package__c/a016F00001iJXMBQA4"
            },
            "Name": "BrightGen Limited",
            "Version__c": "1.30",
            "License__c": "Active",
            "Date_Installed__c": "2018-07-25T07:19:30.000+0000",
            "Date_Updated__c": "2018-07-25T07:19:30.000+0000",
            "Id": "a016F00001iJXMBQA4"
        },
        {
            "attributes": {
                "type": "Installed_Package__c",
                "url": "/services/data/v43.0/sobjects/Installed_Package__c/a016F00001iJXMCQA4"
            },
            "Name": "Salesforce.com",
            "Version__c": "1.7",
            "License__c": "Free",
            "Date_Installed__c": "2018-07-25T07:56:20.000+0000",
            "Date_Updated__c": "2018-07-25T07:56:20.000+0000",
            "Id": "a016F00001iJXMCQA4"
        }
    ],
    "orgId": "00D6

And This is my apex class:

public class SF_SystemOverview {
    Public String endpoint_url  = '/services/apexrest/ClientSFInfo';
    Public List<Client_Org_Information__c> clientOrgSF {set; get;}

    public SF_SystemOverview() {}

    @future(callout=true)
    public static void getSFOverview(List<Id> orgIds){
        SF_SystemOverview newOC = new SF_SystemOverview();
        newOC.execute_SFOverview(orgIds);

    }

    public String execute_SFOverview(List<Id> orgIds){
        List<Client_Org_Information__c> clientS = getOrgInfo(orgIds);
        String end_point;
        String access_token;
        String client_id;
        List<Client_Org_System_Overview__c> toUpdateClientSO = new List<Client_Org_System_Overview__c>();
        List<Client_Org_Installed_Packages__c> toUpdateClientSOP = new List<Client_Org_Installed_Packages__c>();
        if(clientS.size() > 0){

            Client_Org_System_Overview__c sfClientSO = new Client_Org_System_Overview__c();
            Client_Org_Installed_Packages__c sfClientSOP = new Client_Org_Installed_Packages__c();
            for(Client_Org_Information__c org: clientS){

                end_point       = org.Instance_URL__c;
                end_point       += endpoint_url;
                access_token = org.Access_Token__c;
                client_id       = org.client_id__c;

                String JSON_BODY = Send_API(end_point, access_token, client_id);

                Map<String, Object> m = (Map<String, Object>)JSON.deserializeUntyped(JSON_BODY);
                Map<String, Object> SO = (Map<String,Object>)m.get('system_overview');
                Map<String, Object> packageses = (Map<String,Object>)m.get('packages');
                sfClientSO.client_id__c = org.Id;
                sfClientSO.UsedDataStorage__c = integer.valueOf(SO.get('Used_Storage__c'));
                sfClientSO.TotalDataStorage__c = integer.valueOf(SO.get('Total_Storage__c'));
                sfClientSO.RemainingDataStorage__c = integer.valueOf(SO.get('Remaining_Storage__c'));
                sfClientSO.Id = string.valueOf(SO.get('Id'));
                sfClientSO.usedAPI__c = integer.valueOf(SO.get('Requested_API__c'));
                sfClientSO.remApi__c = integer.valueOf(SO.get('Usable_API__c'));
                sfClientSO.maxApi__c = integer.valueOf(SO.get('Max_API__c'));
                sfClientSOP.Name = string.valueOf(packageses.get('Name'));
                sfClientSOP.License__c = string.valueOf(packageses.get('License__c'));
                sfClientSOP.Version__c = string.valueOf(packageses.get('Version__c'));
                sfClientSOP.Install_Date__c = date.valueOf(packageses.get('Date_Installed__c'));
                sfClientSOP.Last_Modified_Date__c = date.valueOf(packageses.get('Date_Updated__c'));
                sfClientSOP.Id = string.valueOf(packageses.get('Id'));

                toUpdateClientSO.add(sfClientSO);
                toUpdateClientSOP.add(sfClientSOP);


            }
         }

        try {
            if(toUpdateClientSO.size() > 0) update toUpdateClientSO;
            if(toUpdateClientSOP.size() > 0) update toUpdateClientSOP;
        }catch(Exception e){
            System.debug('ERROR: '+e.getMessage() + ' ' +e.getStackTraceString());
        }
        return null;
    }
    public String Send_API(String end_point, String access_token, String CLIENT_ID){

        HttpRequest req = new HttpRequest();
        req.setEndpoint(end_point);
        req.setMethod('GET');
        req.setHeader('Authorization' , 'Bearer'+' '+ access_token);
        System.debug('ENDPOINT: '+END_POINT);
        System.debug('Request: '+req);
        Http http = new Http();
        HttpResponse res = http.send(req);
        System.debug('Response: ' + res.getBody());
        return res.getBody();

    }
    public List<Client_Org_Information__c> getOrgInfo(List<Id> orgIds){
        clientOrgSF = [SELECT Id, client_id__c, Instance_URL__c, Access_Token__c FROM Client_Org_Information__c WHERE Id IN: orgIds];
        return clientOrgSF;
    }
}

Any suggestion why I get that error?

1 Answer 1

2

The problem isn't that you're getting the wrong response back (at least, not directly), but really you're trying to nest salesforce callouts, which is not allowed. What's happening here is that SF_SystemOverview#execute_SFOverview is calling /services/apexrest/api/PackageLicense, which calls InsPackages.doGet, which in turn is calling out to another Salesforce endpoint, at which point it crashes. It doesn't matter what you do at that point, it's simply not going to work as you've designed it. You'll need to do whatever logic you were doing in InsPackages.doGet directly in SF_SystemOverview#execute_SFOverview instead. If that's not possible, you're going to need to rethink your entire design, because you've run in to a hard limit. Focus on resolving the "callout loop not allowed" error before worrying about your JSON not deserializing properly.

2
  • Hi @sfdcfox, the loop in callout is already solved, but this error remains, FATAL_ERROR System.TypeException: Invalid conversion from runtime type List to Map. Any suggestions for this? Commented Aug 9, 2018 at 0:14
  • @JanjanDain Map<String, Object> packageses = (Map<String,Object>)m.get('packages'); is wrong. It should be: List<Object> packageses = (List<Object>)m.get('packages'); You need to pay attention to the JSON types.
    – sfdcfox
    Commented Aug 9, 2018 at 0:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .