cumulocity

how to reverse the measurement data using MeasurementFilter in Java SDK for Cumulocity Api?


I am using below code to get the latest measurement API details for specific device but its not returning the data in descending order:

import com.cumulocity.sdk.client.measurement.MeasurementFilter;
import com.cumulocity.sdk.client.Platform;
import com.cumulocity.rest.representation.measurement.MeasurementRepresentation;
    
@Autowired
private Platform platform;

MeasurementFilter filter = new MeasurementFilter().byType("type").bySource("deviceId").byDate(fromDate,dateTo);
Iterable<MeasurementRepresentation> mRep = platform.getMeasurementApi().getMeasurementsByFilter(filter).get().elements(1);
List<MeasurementRepresentation> mRepList = StreamSupport.stream(mRep.spliterator(), false).collect(Collectors.toList());
...

MeasurementFilter api

we can get the latest data using 'revert=true' in Http REST url call..

   ../measurement/measurements?source={deviceId}&type={type}&dateTo=xxx&dateFrom=xxx&revert=true

How we can use 'revert=true' or other way to get measurement details in order using Cumulocity Java SDK? appreciate your help here.


Solution

  • The SDK currently has no out-of-the-box QueryParam for revert parameter so you have to create it yourself:

    import com.cumulocity.sdk.client.Param;
     
    public class RevertParam implements Param {
     
        @Override
        public String getName() {
            return "revert";
        }
     
    }
    

    And then you can combine it with your query. Therefore you to include your Query Param when you use the get() on the MeasurementCollection. You are currently not passing anything but you can pass pageSize and an arbitrary number of QueryParam.

    private Iterable<MeasurementRepresentation> getMeasurementByFilterAndQuery(int pageSize, MeasurementFilter filter, QueryParam... queryParam) {
            MeasurementCollection collection = measurementApi.getMeasurementByFilter(filter);
            Iterable<MeasurementRepresentation> iterable = collection.get(pageSize, queryParam).allPages();
            return iterable;
        }
        
    private Optional<MeasurementRepresentation> getLastMeasurement(GId source) {
                QueryParam revertQueryParam = new QueryParam(new RevertParam(), "true");
                MeasurementFilter filter = new MeasurementFilter()
                        .bySource(source)
                        .byFromDate(new DateTime(0).toDate());
                Iterable<MeasurementRepresentation> iterable = measurementRepository.getMeasurementByFilterAndQuery(1, filter, revertQueryParam);
            if (iterable.iterator().hasNext()) {
                return Optional.of(iterable.iterator().next());
            } else {
                return Optional.absent();
            }
        }
    

    Extending your code it could look like this:

    QueryParam revertQueryParam = new QueryParam(new RevertParam(), "true");
    MeasurementFilter filter = new MeasurementFilter().byType("type").bySource("deviceId").byDate(fromDate,dateTo);
    Iterable<MeasurementRepresentation> mRep = platform.getMeasurementApi().getMeasurementsByFilter(filter).get(1, revertQueryParam);
    List<MeasurementRepresentation> mRepList = StreamSupport.stream(mRep.spliterator(), false).collect(Collectors.toList());
    

    What you did with elements is not incorrect but it is not limiting the API call to just return one value. It would query with defaultPageSize (=5) and then on Iterable level limit it to only return one. The elements() function is more for usage when you need more elements than the maxPageSize (=2000). Then it will handle automatic requesting for additional pages and you can just loop through the Iterable.