com.teradata.benchto.driver.service.BenchmarkServiceClient.java Source code

Java tutorial

Introduction

Here is the source code for com.teradata.benchto.driver.service.BenchmarkServiceClient.java

Source

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

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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);

    @Value("${benchmark-service.url}")
    private String serviceUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Retryable(value = RestClientException.class, backoff = @Backoff(1000))
    public Instant getServiceCurrentTime() {
        Map<String, String> requestParams = ImmutableMap.of("serviceUrl", serviceUrl);
        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<String> generateUniqueBenchmarkNames(
            List<GenerateUniqueNamesRequestItem> generateUniqueNamesRequestItems) {
        Map<String, String> requestParams = ImmutableMap.of("serviceUrl", serviceUrl);
        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<Duration> getBenchmarkSuccessfulExecutionAges(List<String> benchmarkUniqueNames) {
        Map<String, String> requestParams = ImmutableMap.of("serviceUrl", serviceUrl);
        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<String, String> 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<String, String> 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<String, String> 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<String, String> requestParams = requestParams(uniqueBenchmarkName, benchmarkSequenceId);
        requestParams.put("executionSequenceId", executionSequenceId);

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

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

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

    private <T> T postForObject(String url, Object request, Class<T> clazz, Map<String, String> 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 String name;
        private Map<String, String> variables;

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

        public String getName() {
            return name;
        }

        public Map<String, String> getVariables() {
            return variables;
        }

        public static GenerateUniqueNamesRequestItem generateUniqueNamesRequestItem(String name,
                Map<String, String> 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<String, String> attributes = newHashMap();

        public abstract static class AttributeRequestBuilder<T extends AttributeRequest> {
            protected final T request;

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

            public AttributeRequestBuilder<T> 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 Map<String, String> variables = newHashMap();

        private BenchmarkStartRequest() {
        }

        public static class BenchmarkStartRequestBuilder extends AttributeRequestBuilder<BenchmarkStartRequest> {
            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<ExecutionStartRequest> {
            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 List<Measurement> measurements = newArrayList();

        private FinishRequest() {
        }

        public static class FinishRequestBuilder extends AttributeRequestBuilder<FinishRequest> {
            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<Measurement> measurements) {
                request.measurements.addAll(measurements);
                return this;
            }
        }

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