com.google.cloud.logging.spi.DefaultLoggingRpc.java Source code

Java tutorial

Introduction

Here is the source code for com.google.cloud.logging.spi.DefaultLoggingRpc.java

Source

/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.google.cloud.logging.spi;

import com.google.api.gax.grpc.ApiException;
import com.google.api.gax.grpc.ChannelProvider;
import com.google.api.gax.grpc.ExecutorProvider;
import com.google.api.gax.grpc.FixedChannelProvider;
import com.google.api.gax.grpc.FixedExecutorProvider;
import com.google.api.gax.grpc.ProviderManager;
import com.google.api.gax.grpc.UnaryCallSettings;
import com.google.cloud.GrpcServiceOptions.ExecutorFactory;
import com.google.cloud.NoCredentials;
import com.google.cloud.logging.LoggingException;
import com.google.cloud.logging.LoggingOptions;
import com.google.cloud.logging.spi.v2.ConfigServiceV2Api;
import com.google.cloud.logging.spi.v2.ConfigServiceV2Settings;
import com.google.cloud.logging.spi.v2.LoggingServiceV2Api;
import com.google.cloud.logging.spi.v2.LoggingServiceV2Settings;
import com.google.cloud.logging.spi.v2.MetricsServiceV2Api;
import com.google.cloud.logging.spi.v2.MetricsServiceV2Settings;
import com.google.common.base.Function;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.logging.v2.CreateLogMetricRequest;
import com.google.logging.v2.CreateSinkRequest;
import com.google.logging.v2.DeleteLogMetricRequest;
import com.google.logging.v2.DeleteLogRequest;
import com.google.logging.v2.DeleteSinkRequest;
import com.google.logging.v2.GetLogMetricRequest;
import com.google.logging.v2.GetSinkRequest;
import com.google.logging.v2.ListLogEntriesRequest;
import com.google.logging.v2.ListLogEntriesResponse;
import com.google.logging.v2.ListLogMetricsRequest;
import com.google.logging.v2.ListLogMetricsResponse;
import com.google.logging.v2.ListMonitoredResourceDescriptorsRequest;
import com.google.logging.v2.ListMonitoredResourceDescriptorsResponse;
import com.google.logging.v2.ListSinksRequest;
import com.google.logging.v2.ListSinksResponse;
import com.google.logging.v2.LogMetric;
import com.google.logging.v2.LogSink;
import com.google.logging.v2.UpdateLogMetricRequest;
import com.google.logging.v2.UpdateSinkRequest;
import com.google.logging.v2.WriteLogEntriesRequest;
import com.google.logging.v2.WriteLogEntriesResponse;
import com.google.protobuf.Empty;

import io.grpc.ManagedChannel;
import io.grpc.Status.Code;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;

public class DefaultLoggingRpc implements LoggingRpc {

    private final ConfigServiceV2Api configApi;
    private final LoggingServiceV2Api loggingApi;
    private final MetricsServiceV2Api metricsApi;
    private final ScheduledExecutorService executor;
    private final ProviderManager providerManager;
    private final ExecutorFactory<ScheduledExecutorService> executorFactory;

    private boolean closed;

    private static final class InternalLoggingOptions extends LoggingOptions {

        private static final long serialVersionUID = -2107638980310672033L;

        private InternalLoggingOptions(LoggingOptions options) {
            super(options.toBuilder());
        }

        @Override
        protected ExecutorFactory<ScheduledExecutorService> getExecutorFactory() {
            return super.getExecutorFactory();
        }

        @Override
        protected UnaryCallSettings.Builder getApiCallSettings() {
            return super.getApiCallSettings();
        }

        @Override
        protected ChannelProvider getChannelProvider() {
            return super.getChannelProvider();
        }
    }

    public DefaultLoggingRpc(LoggingOptions options) throws IOException {
        InternalLoggingOptions internalOptions = new InternalLoggingOptions(options);
        executorFactory = internalOptions.getExecutorFactory();
        executor = executorFactory.get();
        try {
            ExecutorProvider executorProvider = FixedExecutorProvider.create(executor);
            ChannelProvider channelProvider;
            // todo(mziccard): ChannelProvider should support null/absent credentials for testing
            if (options.getHost().contains("localhost")
                    || options.getCredentials().equals(NoCredentials.getInstance())) {
                ManagedChannel managedChannel = NettyChannelBuilder.forTarget(options.getHost())
                        .negotiationType(NegotiationType.PLAINTEXT).executor(executor).build();
                channelProvider = FixedChannelProvider.create(managedChannel);
            } else {
                channelProvider = internalOptions.getChannelProvider();
            }
            providerManager = ProviderManager.newBuilder().setChannelProvider(channelProvider)
                    .setExecutorProvider(executorProvider).build();
            UnaryCallSettings.Builder callSettingsBuilder = internalOptions.getApiCallSettings();
            ConfigServiceV2Settings.Builder confBuilder = ConfigServiceV2Settings.defaultBuilder()
                    .setExecutorProvider(providerManager).setChannelProvider(providerManager)
                    .applyToAllApiMethods(callSettingsBuilder);
            LoggingServiceV2Settings.Builder logBuilder = LoggingServiceV2Settings.defaultBuilder()
                    .setExecutorProvider(providerManager).setChannelProvider(providerManager)
                    .applyToAllApiMethods(callSettingsBuilder);
            MetricsServiceV2Settings.Builder metricsBuilder = MetricsServiceV2Settings.defaultBuilder()
                    .setExecutorProvider(providerManager).setChannelProvider(providerManager)
                    .applyToAllApiMethods(callSettingsBuilder);
            configApi = ConfigServiceV2Api.create(confBuilder.build());
            loggingApi = LoggingServiceV2Api.create(logBuilder.build());
            metricsApi = MetricsServiceV2Api.create(metricsBuilder.build());
        } catch (Exception ex) {
            throw new IOException(ex);
        }
    }

    private static <V> Future<V> translate(ListenableFuture<V> from, final boolean idempotent,
            int... returnNullOn) {
        final Set<Integer> returnNullOnSet = Sets.newHashSetWithExpectedSize(returnNullOn.length);
        for (int value : returnNullOn) {
            returnNullOnSet.add(value);
        }
        return Futures.catching(from, ApiException.class, new Function<ApiException, V>() {
            @Override
            public V apply(ApiException exception) {
                if (returnNullOnSet.contains(exception.getStatusCode().value())) {
                    return null;
                }
                throw new LoggingException(exception, idempotent);
            }
        });
    }

    @Override
    public Future<LogSink> create(CreateSinkRequest request) {
        return translate(configApi.createSinkCallable().futureCall(request), true);
    }

    @Override
    public Future<LogSink> update(UpdateSinkRequest request) {
        return translate(configApi.updateSinkCallable().futureCall(request), true);
    }

    @Override
    public Future<LogSink> get(GetSinkRequest request) {
        return translate(configApi.getSinkCallable().futureCall(request), true, Code.NOT_FOUND.value());
    }

    @Override
    public Future<ListSinksResponse> list(ListSinksRequest request) {
        return translate(configApi.listSinksCallable().futureCall(request), true);
    }

    @Override
    public Future<Empty> delete(DeleteSinkRequest request) {
        return translate(configApi.deleteSinkCallable().futureCall(request), true, Code.NOT_FOUND.value());
    }

    @Override
    public Future<Empty> delete(DeleteLogRequest request) {
        return translate(loggingApi.deleteLogCallable().futureCall(request), true, Code.NOT_FOUND.value());
    }

    @Override
    public Future<WriteLogEntriesResponse> write(WriteLogEntriesRequest request) {
        return translate(loggingApi.writeLogEntriesCallable().futureCall(request), false);
    }

    @Override
    public Future<ListLogEntriesResponse> list(ListLogEntriesRequest request) {
        return translate(loggingApi.listLogEntriesCallable().futureCall(request), true);
    }

    @Override
    public Future<ListMonitoredResourceDescriptorsResponse> list(ListMonitoredResourceDescriptorsRequest request) {
        return translate(loggingApi.listMonitoredResourceDescriptorsCallable().futureCall(request), true);
    }

    @Override
    public Future<LogMetric> create(CreateLogMetricRequest request) {
        return translate(metricsApi.createLogMetricCallable().futureCall(request), true);
    }

    @Override
    public Future<LogMetric> update(UpdateLogMetricRequest request) {
        return translate(metricsApi.updateLogMetricCallable().futureCall(request), true);
    }

    @Override
    public Future<LogMetric> get(GetLogMetricRequest request) {
        return translate(metricsApi.getLogMetricCallable().futureCall(request), true, Code.NOT_FOUND.value());
    }

    @Override
    public Future<ListLogMetricsResponse> list(ListLogMetricsRequest request) {
        return translate(metricsApi.listLogMetricsCallable().futureCall(request), true);
    }

    @Override
    public Future<Empty> delete(DeleteLogMetricRequest request) {
        return translate(metricsApi.deleteLogMetricCallable().futureCall(request), true, Code.NOT_FOUND.value());
    }

    @Override
    public void close() throws Exception {
        if (closed) {
            return;
        }
        closed = true;
        configApi.close();
        loggingApi.close();
        metricsApi.close();
        providerManager.getChannel().shutdown();
        executorFactory.release(executor);
    }
}