/* * 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 gobblin.util.limiter; import com.google.common.collect.ImmutableMap; import com.linkedin.restli.client.RestClient; import gobblin.broker.ResourceCoordinate; import gobblin.broker.ResourceInstance; import gobblin.broker.iface.ConfigView; import gobblin.broker.iface.NotConfiguredException; import gobblin.broker.iface.ScopeType; import gobblin.broker.iface.ScopedConfigView; import gobblin.broker.iface.SharedResourceFactory; import gobblin.broker.iface.SharedResourceFactoryResponse; import gobblin.broker.iface.SharedResourcesBroker; import gobblin.metrics.broker.MetricContextFactory; import gobblin.metrics.broker.MetricContextKey; import gobblin.metrics.broker.SubTaggedMetricContextKey; import gobblin.restli.SharedRestClientKey; import gobblin.util.limiter.broker.SharedLimiterKey; import lombok.extern.slf4j.Slf4j; /** * A {@link gobblin.util.limiter.broker.SharedLimiterFactory} that creates {@link RestliServiceBasedLimiter}s. It * automatically acquires a {@link RestClient} from the broker for restli service name {@link #RESTLI_SERVICE_NAME}. */ @Slf4j public class RestliLimiterFactory<S extends ScopeType<S>> implements SharedResourceFactory<RestliServiceBasedLimiter, SharedLimiterKey, S> { public static final String FACTORY_NAME = "limiter.restli"; public static final String RESTLI_SERVICE_NAME = "throttling"; public static final String SERVICE_IDENTIFIER_KEY = "serviceId"; @Override public String getName() { return FACTORY_NAME; } @Override public SharedResourceFactoryResponse<RestliServiceBasedLimiter> createResource(SharedResourcesBroker<S> broker, ScopedConfigView<S, SharedLimiterKey> config) throws NotConfiguredException { S scope = config.getScope(); if (scope != scope.rootScope()) { return new ResourceCoordinate<>(this, config.getKey(), scope.rootScope()); } String serviceIdentifier = config.getConfig().hasPath(SERVICE_IDENTIFIER_KEY) ? config.getConfig().getString(SERVICE_IDENTIFIER_KEY) : "UNKNOWN"; String resourceLimited = config.getKey().getResourceLimitedPath(); MetricContextKey metricContextKey = new SubTaggedMetricContextKey(RestliServiceBasedLimiter.class.getSimpleName() + "_" + resourceLimited, ImmutableMap.of("resourceLimited", resourceLimited)); return new ResourceInstance<>( RestliServiceBasedLimiter.builder() .resourceLimited(resourceLimited) .serviceIdentifier(serviceIdentifier) .metricContext(broker.getSharedResource(new MetricContextFactory<S>(), metricContextKey)) .requestSender(broker.getSharedResource(new RedirectAwareRestClientRequestSender.Factory<S>(), new SharedRestClientKey(RESTLI_SERVICE_NAME))) .build() ); } @Override public S getAutoScope(SharedResourcesBroker<S> broker, ConfigView<S, SharedLimiterKey> config) { return broker.selfScope().getType().rootScope(); } }