blob: 2f682cdf6d8c64a3936f1d76a10f81fbee24c6da [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.bedstead.metricsrecorder;
import com.android.bedstead.nene.exceptions.NeneException;
import com.android.queryable.Queryable;
import com.android.queryable.queries.BooleanQuery;
import com.android.queryable.queries.BooleanQueryHelper;
import com.android.queryable.queries.IntegerQuery;
import com.android.queryable.queries.IntegerQueryHelper;
import com.android.queryable.queries.ListQueryHelper;
import com.android.queryable.queries.StringQuery;
import com.android.queryable.queries.StringQueryHelper;
import java.time.Duration;
import java.time.Instant;
public class MetricQueryBuilder implements Queryable {
private final EnterpriseMetricsRecorder mRecorder;
private boolean hasStartedFetchingResults = false;
private int mSkippedNextResults = 0;
private int mSkippedPollResults = 0;
private final IntegerQueryHelper<MetricQueryBuilder> mTypeQuery =
new IntegerQueryHelper<>(this);
private final StringQueryHelper<MetricQueryBuilder> mAdminPackageNameQuery =
new StringQueryHelper<>(this);
private final BooleanQueryHelper<MetricQueryBuilder> mBooleanQuery =
new BooleanQueryHelper<>(this);
private final ListQueryHelper<MetricQueryBuilder, String, StringQuery<?>> mStringsQuery =
new ListQueryHelper<>(this);
private final IntegerQueryHelper<MetricQueryBuilder> mIntegerQuery =
new IntegerQueryHelper<>(this);
MetricQueryBuilder(EnterpriseMetricsRecorder recorder) {
mRecorder = recorder;
}
/** Query for {@link EnterpriseMetricInfo#type()}. */
public IntegerQuery<MetricQueryBuilder> whereType() {
if (hasStartedFetchingResults) {
throw new IllegalStateException("Cannot modify query after fetching results");
}
return mTypeQuery;
}
/** Query for {@link EnterpriseMetricInfo#adminPackageName()}. */
public StringQuery<MetricQueryBuilder> whereAdminPackageName() {
if (hasStartedFetchingResults) {
throw new IllegalStateException("Cannot modify query after fetching results");
}
return mAdminPackageNameQuery;
}
/** Query for {@link EnterpriseMetricInfo#Boolean()}. */
public BooleanQuery<MetricQueryBuilder> whereBoolean() {
if (hasStartedFetchingResults) {
throw new IllegalStateException("Cannot modify query after fetching results");
}
return mBooleanQuery;
}
/** Query for {@link EnterpriseMetricInfo#integer()}. */
public IntegerQuery<MetricQueryBuilder> whereInteger() {
if (hasStartedFetchingResults) {
throw new IllegalStateException("Cannot modify query after fetching results");
}
return mIntegerQuery;
}
public ListQueryHelper<MetricQueryBuilder, String, StringQuery<?>> whereStrings() {
if (hasStartedFetchingResults) {
throw new IllegalStateException("Cannot modify query after fetching results");
}
return mStringsQuery;
}
public EnterpriseMetricInfo get() {
return get(/* skipResults= */ 0);
}
private EnterpriseMetricInfo get(int skipResults) {
hasStartedFetchingResults = true;
for (EnterpriseMetricInfo m : mRecorder.fetchLatestData()) {
if (matches(m)) {
skipResults -= 1;
if (skipResults < 0) {
return m;
}
}
}
return null;
}
public EnterpriseMetricInfo next() {
hasStartedFetchingResults = true;
EnterpriseMetricInfo nextResult = get(mSkippedNextResults);
if (nextResult != null) {
mSkippedNextResults++;
}
return nextResult;
}
public EnterpriseMetricInfo poll() {
return poll(Duration.ofSeconds(30));
}
public EnterpriseMetricInfo poll(Duration timeout) {
hasStartedFetchingResults = true;
Instant endTime = Instant.now().plus(timeout);
while (Instant.now().isBefore(endTime)) {
EnterpriseMetricInfo nextResult = get(mSkippedPollResults);
if (nextResult != null) {
mSkippedPollResults++;
return nextResult;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new NeneException("Interrupted while polling", e);
}
}
return null;
}
private boolean matches(EnterpriseMetricInfo metric) {
return mAdminPackageNameQuery.matches(metric.adminPackageName())
&& mTypeQuery.matches(metric.type())
&& mBooleanQuery.matches(metric.Boolean())
&& mStringsQuery.matches(metric.strings())
&& mIntegerQuery.matches(metric.integer());
}
@Override
public String describeQuery(String fieldName) {
return "{" + Queryable.joinQueryStrings(
mAdminPackageNameQuery.describeQuery("adminPackageName"),
mTypeQuery.describeQuery("type"),
mBooleanQuery.describeQuery("boolean"),
mStringsQuery.describeQuery("strings"),
mIntegerQuery.describeQuery("integer")
) + "}";
}
@Override
public String toString() {
return describeQuery("");
}
}