| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you 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 org.apache.calcite.avatica.server; |
| |
| import org.apache.calcite.avatica.metrics.MetricsSystem; |
| import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration; |
| import org.apache.calcite.avatica.metrics.MetricsSystemFactory; |
| import org.apache.calcite.avatica.metrics.MetricsSystemLoader; |
| import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem; |
| import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration; |
| import org.apache.calcite.avatica.remote.Driver; |
| import org.apache.calcite.avatica.remote.Service; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.ServiceLoader; |
| |
| /** |
| * Factory that instantiates the desired implementation, typically differing on the method |
| * used to serialize messages, for use in the Avatica server. |
| */ |
| public class HandlerFactory { |
| private static final Logger LOG = LoggerFactory.getLogger(HandlerFactory.class); |
| |
| /** |
| * Constructs the desired implementation for the given serialization method with metrics. |
| * |
| * @param service The underlying {@link Service}. |
| * @param serialization The desired message serialization. |
| * @return The {@link AvaticaHandler}. |
| */ |
| public AvaticaHandler getHandler(Service service, Driver.Serialization serialization) { |
| return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance()); |
| } |
| |
| /** |
| * Constructs the desired implementation for the given serialization method and server |
| * configuration with metrics. |
| * |
| * @param service The underlying {@link Service}. |
| * @param serialization The desired message serialization. |
| * @param serverConfig Avatica server configuration or null. |
| * @return The {@link AvaticaHandler}. |
| */ |
| public AvaticaHandler getHandler(Service service, Driver.Serialization serialization, |
| AvaticaServerConfiguration serverConfig) { |
| return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance(), |
| serverConfig); |
| } |
| |
| /** |
| * Constructs the desired implementation for the given serialization method with metrics. |
| * |
| * @param service The underlying {@link Service}. |
| * @param serialization The desired message serialization. |
| * @param metricsConfig Configuration for the {@link MetricsSystem}. |
| * @return The {@link AvaticaHandler}. |
| */ |
| public AvaticaHandler getHandler(Service service, Driver.Serialization serialization, |
| MetricsSystemConfiguration<?> metricsConfig) { |
| return getHandler(service, serialization, metricsConfig, null); |
| } |
| |
| /** |
| * Constructs the desired implementation for the given serialization method and server |
| * configuration with metrics. |
| * |
| * @param service The underlying {@link Service} |
| * @param serialization The serializatio mechanism to use |
| * @param metricsConfig Configuration for the {@link MetricsSystem}. |
| * @param serverConfig Avatica server configuration or null |
| * @return An {@link AvaticaHandler} |
| */ |
| public AvaticaHandler getHandler(Service service, Driver.Serialization serialization, |
| MetricsSystemConfiguration<?> metricsConfig, AvaticaServerConfiguration serverConfig) { |
| if (null == metricsConfig) { |
| metricsConfig = NoopMetricsSystemConfiguration.getInstance(); |
| } |
| MetricsSystem metrics = MetricsSystemLoader.load(metricsConfig); |
| |
| switch (serialization) { |
| case JSON: |
| return new AvaticaJsonHandler(service, metrics, serverConfig); |
| case PROTOBUF: |
| return new AvaticaProtobufHandler(service, metrics, serverConfig); |
| default: |
| throw new IllegalArgumentException("Unknown Avatica handler for " + serialization.name()); |
| } |
| } |
| |
| /** |
| * Load a {@link MetricsSystem} using ServiceLoader to create a {@link MetricsSystemFactory}. |
| * |
| * @param config State to pass to the factory for initialization. |
| * @return A {@link MetricsSystem} instance. |
| */ |
| MetricsSystem loadMetricsSystem(MetricsSystemConfiguration<?> config) { |
| ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class); |
| List<MetricsSystemFactory> availableFactories = new ArrayList<>(); |
| for (MetricsSystemFactory factory : loader) { |
| availableFactories.add(factory); |
| } |
| |
| if (1 == availableFactories.size()) { |
| // One and only one instance -- what we want |
| MetricsSystemFactory factory = availableFactories.get(0); |
| LOG.info("Loaded MetricsSystem {}", factory.getClass()); |
| return factory.create(config); |
| } else if (availableFactories.isEmpty()) { |
| // None-provided default to no metrics |
| LOG.info("No metrics implementation available on classpath. Using No-op implementation"); |
| return NoopMetricsSystem.getInstance(); |
| } else { |
| // Tell the user they're doing something wrong, and choose the first impl. |
| StringBuilder sb = new StringBuilder(); |
| for (MetricsSystemFactory factory : availableFactories) { |
| if (sb.length() > 0) { |
| sb.append(", "); |
| } |
| sb.append(factory.getClass()); |
| } |
| LOG.warn("Found multiple MetricsSystemFactory implementations: {}." |
| + " Using No-op implementation", sb); |
| return NoopMetricsSystem.getInstance(); |
| } |
| } |
| } |
| |
| // End HandlerFactory.java |