QueryParam in SDK not working

Product/components used and version/fix level:

Cumulocity Production

Detailed explanation of the problem:

Hi,

I am using a custom query and I created a class as CustomQueryParam where I am fetching my devices based on creationTime. My service is a scheduled service and it is deployed on my tenant. First day when my service runs, it fetches the data based on current time only but next day when it runs it takes the previous time only, it doesn’t fetch the time from the customQueryParam.

My Code:

CustomQueryParam Class


public class CustomQueryParam extends QueryParam {

    private final Logger logger = Logger.getLogger(this.getClass().getName());

    private static final Param QUERY_PARAM = () -> "query";

    private static final CustomQueryParam INSTANCE = new CustomQueryParam();

    private CustomQueryParam() {
        super(QUERY_PARAM, URLEncoder.encode("creationTime.date ge " + "'" + CustomUtil.getDateWithTime() + "'", StandardCharsets.UTF_8));
        logger.info("Creation Time Query Param as: creationTime.date ge  + '" + CustomUtil.getDateWithTime() + "'");
    }

    public static CustomQueryParam getInstance() {
        return INSTANCE;
    }
}

CustomUtil Class

public class CustomUtil {
    public static String getDateWithTime() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        final DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime()) +"T00:00:00.000Z";
    }
}

MyService class method:

public void getDevices() {
        List<Map<String, String>> deviceData = new ArrayList<>();
        subscriptionsService.runForEachTenant(() -> {

            InventoryFilter deviceFilter = new InventoryFilter().byFragmentType("c8y_IsDevice");

            Iterable<ManagedObjectRepresentation> mObjColl = inventoryApi.getManagedObjectsByFilter(deviceFilter)

                    .get(2000, WithParentsParameter.getInstance(), CustomQueryParam.getInstance()).allPages();

            logger.info("API Call: " + inventoryApi.getManagedObjectsByFilter(deviceFilter)
                    .get(2000, WithParentsParameter.getInstance(), CustomQueryParam.getInstance()).getSelf());

            List<ManagedObjectRepresentation> mObjList = StreamSupport.stream(mObjColl.spliterator(), false).toList();
            System.out.println();
            logger.info("No. of devices received: "+mObjList.size());
});
}

Now in the deployed service logs:
First time it ran since deployment

2023-07-08 03:00:00.002  INFO 1 --- [   scheduling-1] c.s.r.S.Schedule.Scheduler               : Current Time: 2023-07-08T01:00:00.000Z
2023-07-08 03:00:00.224  INFO 1 --- [   scheduling-1] c.s.r.S.utils.CustomQueryParam           : Creation Time Query Param as: creationTime.date ge  + '2023-07-07T00:00:00.000Z'
2023-07-08 03:00:01.054  INFO 1 --- [   scheduling-1] c.s.r.S.Job.CumulocityService            : API Call: {{url}}/inventory/managedObjects?query=creationTime.date%20ge%20'2023-07-07T00:00:00.000Z'&pageSize=2000&withParents=true&fragmentType=c8y_IsDevice&currentPage=1

When it ran on 2nd day:

2023-07-09 03:00:00.001  INFO 1 --- [   scheduling-1] c.s.r.S.Schedule.Scheduler               : Current Time: 2023-07-09T01:00:00.000Z
2023-07-09 03:00:02.931  INFO 1 --- [   scheduling-1] c.s.r.S.Job.CumulocityService            : API Call: http://t173516.iot-dev.solenis.com/inventory/managedObjects?query=creationTime.date%20ge%20'2023-07-07T00:00:00.000Z'&pageSize=2000&withParents=true&fragmentType=c8y_IsDevice&currentPage=1

Here you can see we didnt get that CustomQueryParam log it directly jumped to API Call log by assuming the first time since deployment in creationTime.getInstance method.

Similarly, today this happened as well so why is this happening? Do you know what could be the issue here :thinking:

Hope you understood my question.

Thanks & Regards,
Samanyu

Your log output is defined within the constructor of CustomQueryParam. However, this class is implemented as singleton, so it will be instantiated only once. CustomQueryParam.getInstance() only returns the existing INSTANCE object and does not create a new one → constructor not executed, no log line to expect.

Okay that makes much more sense. Could you please let me know how I can configure my custom class to fetch the devices according to my use case. I need to fetch the devices based on creation Time so where should I place my creationTime.ge line

super(QUERY_PARAM, URLEncoder.encode("creationTime.date ge " + "'" + CustomUtil.getDateWithTime() + "'", StandardCharsets.UTF_8));

apart from constructor.

Hi Samanyu,

for this topic we discussed already in a different thread.
May I know why this solution does not work for you for the “query” part?

You can use it like this:

QueryParam queryParam = CustomQueryParam.QUERY.setValue("creationTime.date ge " + "'" + CustomUtil.getDateWithTime() + "'").toQueryParam();

Regards, Kai

2 Likes

Hi Kai,

Yeah, but that time I went with the basic approach that I did thinking that it is right :laughing: , but anyway thank you for your help :slight_smile:. I have implemented what you said, just need to see if it works for 2 days straight.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.