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

org.appenders.log4j2.elasticsearch.ahc.ClientProviderPoliciesRegistry Maven / Gradle / Ivy

Go to download

Log4j2 Appender plugin pushing logs in batches to Elasticsearch (2.x/5.x/6.x/7.x/8.x) clusters

The newest version!
package org.appenders.log4j2.elasticsearch.ahc;

/*-
 * #%L
 * log4j2-elasticsearch
 * %%
 * Copyright (C) 2022 Rafal Foltynski
 * %%
 * 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.
 * #L%
 */

import org.appenders.log4j2.elasticsearch.ClientProvider;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;

import static org.appenders.core.logging.InternalLogging.getLogger;

/**
 * Stores and retrieves {@link ClientProviderPolicy}-ies.
 */
public class ClientProviderPoliciesRegistry {

    private final Map> copyingPolicies = new HashMap<>();

    public ClientProviderPoliciesRegistry() {
        register(new InheritServerUrisConfig());
        register(new InheritSecurityConfig());
    }

    /**
     * @return list of available policies
     */
    final List availablePolicies() {
        final List validPolicies = new ArrayList<>(Arrays.asList("shared", "none"));
        validPolicies.addAll(copyingPolicies.keySet());
        return validPolicies;
    }

    /**
     * Registers given {@link CopyingConfigPolicy}.
     *
     * @param policy policy to register
     */
    final void register(final CopyingConfigPolicy policy) {
        copyingPolicies.put(policy.getName(), policy);
    }

    /**
     * Resolves {@link ClientProviderPolicy} from given policy list.
     *
     * By default, following policies are available:
     * 
    *
  • serverList - copies uris config from applied {@link ClientProvider} to initial {@link ClientProvider}
  • *
  • security - copies security config from applied {@link ClientProvider} to initial {@link ClientProvider}
  • *
  • shared - reuses applied {@link ClientProvider} and ignores initial {@link ClientProvider}
  • *
  • none - ignores applied {@link ClientProvider} and uses initial {@link ClientProvider}
  • *
* * shared and none can only be used exclusively, e.g. ["shared"] or ["none"]. If any other policy is present in the given list, exception will be thrown. * * serverList and security are {@link CopyingConfigPolicy}-ies and can be mixed with other {@link CopyingConfigPolicy}-ies, e.g.: ["serverList", "security", "myCustomCopyingPolicy"]. * * @param policies policy names * @param initialClientProvider {@link ClientProviderPolicy} to apply the changes to * @return resolved {@link ClientProviderPolicy} if policies list was valid, throws otherwise * */ public final ClientProviderPolicy get(final Set policies, final HttpClientProvider initialClientProvider) { validatePolicyList(policies); if (isValidExclusivePolicy(policies, "shared")) { return new SharedHttpClient(); } if (isValidExclusivePolicy(policies, "none")) { return new NewHttpClient(initialClientProvider); } final CopyingConfigPolicyChain propertiesProcessor = new CopyingConfigPolicyChain(initialClientProvider); for (String policyName : policies) { propertiesProcessor.add(copyingPolicies.get(policyName)); } return propertiesProcessor; } private void validatePolicyList(final Set policies) { if (policies == null || policies.isEmpty()) { throw new IllegalArgumentException("Policy list must present. Valid policies: " + availablePolicies()); } final List availablePolicies = availablePolicies(); for (String policyName: policies) { if (!availablePolicies.contains(policyName)) { throw new IllegalArgumentException("Invalid policy specified: [" + policyName + "]. Available policies: " + availablePolicies); } } } private boolean isValidExclusivePolicy(final Set policies, final String shared) { if (policies.contains(shared)) { ensureNoOtherPolicies(policies, shared); return true; } return false; } private void ensureNoOtherPolicies(final Set policies, final String policyName) { if (policies.size() > 1) { throw new IllegalArgumentException("Cannot apply other policies when [" + policyName + "] policy is used"); } } /** * Allows to define mapping between two {@link ClientProvider} instances. * * @param client type */ public interface CopyingConfigPolicy { /** * @return policy name to use on {@link #get(Set, HttpClientProvider)} calls. */ String getName(); /** * Copies properties from {@code source} to {@code target}. * * @param source source * @param target target */ void copy(ClientProvider source, ClientProvider target); } /** * This API is highly experimental. Consider private. */ static class PropertiesMapper { private PropertiesMapper() { // utility class } static void copyProperty(final String propertyName, final Supplier sourceValueProvider, final Supplier targetValueProvider, final Consumer valueConsumer) { if (!isEmpty(targetValueProvider.get())) { getLogger().debug("{}: Skipping [{}] as target value is not empty", PropertiesMapper.class.getSimpleName(), propertyName); return; } if (isEmpty(sourceValueProvider.get())) { getLogger().debug("{}: Skipping [{}] as source value is empty", PropertiesMapper.class.getSimpleName(), propertyName); return; } valueConsumer.accept(sourceValueProvider.get()); } private static boolean isEmpty(final T value) { if (value == null) { return true; } if (value instanceof String) { return ((String)value).trim().isEmpty(); } if (value instanceof Collection) { return ((Collection)value).isEmpty(); } return false; } } private static class CopyingConfigPolicyChain implements ClientProviderPolicy { private final List> policies = new ArrayList<>(); private final ClientProvider target; public CopyingConfigPolicyChain(final ClientProvider target) { this.target = target; } void add(final CopyingConfigPolicy policy) { this.policies.add(policy); } @Override public ClientProvider apply(final ClientProvider source) { process(source, target); getLogger().info("{}: Properties processed. Resolved config: {}", CopyingConfigPolicyChain.class.getSimpleName(), target); return target; } private void process(final ClientProvider source, final ClientProvider target) { for (CopyingConfigPolicy policy : policies) { policy.copy(source, target); } } } private static class NewHttpClient implements ClientProviderPolicy { private final HttpClientProvider target; private NewHttpClient(final HttpClientProvider httpClientProvider) { this.target = httpClientProvider; } @Override public ClientProvider apply(final ClientProvider source) { getLogger().info("{}: Parent config ignored. Resolved config: {}", NewHttpClient.class, target); return target; } } private static class SharedHttpClient implements ClientProviderPolicy { @Override public ClientProvider apply(final ClientProvider source) { getLogger().info("{}: Parent config reused. Resolved config: {}", SharedHttpClient.class.getSimpleName(), source); return source; } } private static class InheritServerUrisConfig implements CopyingConfigPolicy { @Override public String getName() { return "serverList"; } @Override public void copy(final ClientProvider source, final ClientProvider target) { final HttpClientFactory.Builder src = ((HttpClientProvider)source).getHttpClientFactoryBuilder(); final HttpClientFactory.Builder builder = ((HttpClientProvider)target).getHttpClientFactoryBuilder(); PropertiesMapper.copyProperty("serverList", () -> src.serverList, () -> builder.serverList, builder::withServerList); } } private static class InheritSecurityConfig implements CopyingConfigPolicy { @Override public String getName() { return "security"; } @Override public void copy(final ClientProvider source, final ClientProvider target) { final HttpClientFactory.Builder src = ((HttpClientProvider)source).getHttpClientFactoryBuilder(); final HttpClientFactory.Builder builder = ((HttpClientProvider)target).getHttpClientFactoryBuilder(); PropertiesMapper.copyProperty("auth", () -> src.auth, () -> builder.auth, builder::withAuth); PropertiesMapper.copyProperty("realm", () -> src.realm, () -> builder.realm, builder::withRealm); PropertiesMapper.copyProperty("sslEngineFactory", () -> src.sslEngineFactory, () -> builder.sslEngineFactory, builder::withSslEngineFactory); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy