All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.trino.benchto.driver.service.BenchmarkServiceClient Maven / Gradle / Ivy

/*
 * 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 io.trino.benchto.driver.service;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.trino.benchto.driver.BenchmarkProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriTemplate;

import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static java.util.Objects.requireNonNull;

@Component
public class BenchmarkServiceClient
{
    private static final Logger LOGGER = LoggerFactory.getLogger(BenchmarkServiceClient.class);

    @Autowired
    private BenchmarkProperties properties;

    @Autowired
    private RestTemplate restTemplate;

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public Instant getServiceCurrentTime()
    {
        Map requestParams = ImmutableMap.of("serviceUrl", properties.getServiceURL());
        Long serviceCurrentTime = postForObject("{serviceUrl}/v1/time/current-time-millis", null, Long.class, requestParams);
        return Instant.ofEpochMilli(requireNonNull(serviceCurrentTime, "service returned null time"));
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public List generateUniqueBenchmarkNames(List generateUniqueNamesRequestItems)
    {
        Map requestParams = ImmutableMap.of("serviceUrl", properties.getServiceURL());
        String[] uniqueNames = postForObject("{serviceUrl}/v1/benchmark/generate-unique-names", generateUniqueNamesRequestItems, String[].class, requestParams);
        return ImmutableList.copyOf(uniqueNames);
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public List getBenchmarkSuccessfulExecutionAges(List benchmarkUniqueNames)
    {
        Map requestParams = ImmutableMap.of("serviceUrl", properties.getServiceURL());
        Duration[] ages = postForObject("{serviceUrl}/v1/benchmark/get-successful-execution-ages", benchmarkUniqueNames, Duration[].class, requestParams);
        return ImmutableList.copyOf(ages);
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public String startBenchmark(String uniqueBenchmarkName, String benchmarkSequenceId, BenchmarkStartRequest request)
    {
        Map requestParams = requestParams(uniqueBenchmarkName, benchmarkSequenceId);

        return postForObject("{serviceUrl}/v1/benchmark/{uniqueBenchmarkName}/{benchmarkSequenceId}/start", request, requestParams);
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public void finishBenchmark(String uniqueBenchmarkName, String benchmarkSequenceId, FinishRequest request)
    {
        Map requestParams = requestParams(uniqueBenchmarkName, benchmarkSequenceId);

        postForObject("{serviceUrl}/v1/benchmark/{uniqueBenchmarkName}/{benchmarkSequenceId}/finish", request, requestParams);
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public void startExecution(String uniqueBenchmarkName, String benchmarkSequenceId, String executionSequenceId, ExecutionStartRequest request)
    {
        Map requestParams = requestParams(uniqueBenchmarkName, benchmarkSequenceId);
        requestParams.put("executionSequenceId", executionSequenceId);

        postForObject("{serviceUrl}/v1/benchmark/{uniqueBenchmarkName}/{benchmarkSequenceId}/execution/{executionSequenceId}/start", request, requestParams);
    }

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public void finishExecution(String uniqueBenchmarkName, String benchmarkSequenceId, String executionSequenceId, FinishRequest request)
    {
        Map requestParams = requestParams(uniqueBenchmarkName, benchmarkSequenceId);
        requestParams.put("executionSequenceId", executionSequenceId);

        postForObject("{serviceUrl}/v1/benchmark/{uniqueBenchmarkName}/{benchmarkSequenceId}/execution/{executionSequenceId}/finish", request, requestParams);
    }

    private Map requestParams(String uniqueBenchmarkName, String benchmarkSequenceId)
    {
        Map params = newHashMap();
        params.put("serviceUrl", properties.getServiceURL());
        params.put("uniqueBenchmarkName", uniqueBenchmarkName);
        params.put("benchmarkSequenceId", benchmarkSequenceId);
        return params;
    }

    private String postForObject(String url, Object request, Map requestParams)
    {
        return postForObject(url, request, String.class, requestParams);
    }

    private  T postForObject(String url, Object request, Class clazz, Map requestParams)
    {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Post object to benchmark service on URL: {}, with request: {}",
                    new UriTemplate(url).expand(requestParams),
                    request);
        }

        return restTemplate.postForObject(url, request, clazz, requestParams);
    }

    public static class GenerateUniqueNamesRequestItem
    {
        private final String name;
        private final Map variables;

        private GenerateUniqueNamesRequestItem(String name, Map variables)
        {
            this.name = name;
            this.variables = variables;
        }

        public String getName()
        {
            return name;
        }

        public Map getVariables()
        {
            return variables;
        }

        public static GenerateUniqueNamesRequestItem generateUniqueNamesRequestItem(String name, Map variables)
        {
            return new GenerateUniqueNamesRequestItem(name, variables);
        }

        @Override
        public String toString()
        {
            return toStringHelper(this)
                    .add("name", name)
                    .add("variables", variables)
                    .toString();
        }
    }

    @SuppressWarnings("unused")
    @JsonAutoDetect(fieldVisibility = ANY)
    public abstract static class AttributeRequest
    {
        protected Map attributes = newHashMap();

        public abstract static class AttributeRequestBuilder
        {
            protected final T request;

            public AttributeRequestBuilder(T request)
            {
                this.request = request;
            }

            public AttributeRequestBuilder addAttribute(String name, String value)
            {
                request.attributes.put(name, value);
                return this;
            }

            public T build()
            {
                return request;
            }
        }
    }

    @SuppressWarnings("unused")
    public static class BenchmarkStartRequest
            extends AttributeRequest
    {
        private String name;
        private String environmentName;
        private final Map variables = newHashMap();

        private BenchmarkStartRequest()
        {
        }

        public static class BenchmarkStartRequestBuilder
                extends AttributeRequestBuilder
        {
            public BenchmarkStartRequestBuilder(String name)
            {
                super(new BenchmarkStartRequest());
                request.name = name;
            }

            public BenchmarkStartRequestBuilder environmentName(String environmentName)
            {
                request.environmentName = environmentName;
                return this;
            }

            public BenchmarkStartRequestBuilder addVariable(String name, String value)
            {
                request.variables.put(name, value);
                return this;
            }
        }

        @Override
        public String toString()
        {
            return toStringHelper(this)
                    .add("name", name)
                    .add("environmentName", environmentName)
                    .add("variables", variables)
                    .add("attributes", attributes)
                    .toString();
        }
    }

    public static class ExecutionStartRequest
            extends AttributeRequest
    {
        private ExecutionStartRequest()
        {
        }

        public static class ExecutionStartRequestBuilder
                extends AttributeRequestBuilder
        {
            public ExecutionStartRequestBuilder()
            {
                super(new ExecutionStartRequest());
            }
        }

        @Override
        public String toString()
        {
            return toStringHelper(this)
                    .add("attributes", attributes)
                    .toString();
        }
    }

    public static class FinishRequest
            extends AttributeRequest
    {
        public enum Status
        {
            STARTED, ENDED, FAILED
        }

        private Status status;
        private Instant endTime;
        private final List measurements = newArrayList();

        private FinishRequest()
        {
        }

        public static class FinishRequestBuilder
                extends AttributeRequestBuilder
        {
            public FinishRequestBuilder()
            {
                super(new FinishRequest());
            }

            public FinishRequestBuilder withStatus(Status status)
            {
                request.status = status;
                return this;
            }

            public FinishRequestBuilder withEndTime(Instant endTime)
            {
                request.endTime = endTime;
                return this;
            }

            public FinishRequestBuilder addMeasurement(Measurement measurement)
            {
                request.measurements.add(measurement);
                return this;
            }

            public FinishRequestBuilder addMeasurements(Collection measurements)
            {
                request.measurements.addAll(measurements);
                return this;
            }

            public FinishRequestBuilder addQueryInfo(String queryInfo)
            {
                return this;
            }
        }

        @Override
        public String toString()
        {
            return toStringHelper(this)
                    .add("measurements", measurements)
                    .add("status", status)
                    .add("endTime", endTime)
                    .add("attributes", attributes)
                    .toString();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy