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

com.turbospaces.boot.test.AbstractSpringBootTestContextBootstrapper Maven / Gradle / Ivy

package com.turbospaces.boot.test;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.concurrent.ConcurrentException;
import org.apache.commons.lang3.concurrent.LazyInitializer;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.cloud.SmartCloud;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.kafka.test.EmbeddedKafkaBroker;
import org.springframework.kafka.test.EmbeddedKafkaZKBroker;
import org.springframework.kafka.test.core.BrokerAddress;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextLoader;

import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.turbospaces.boot.AbstractBootstrap;
import com.turbospaces.cfg.ApplicationConfig;
import com.turbospaces.cfg.ApplicationProperties;
import com.turbospaces.ups.KafkaServiceInfo;
import com.turbospaces.ups.RawServiceInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractSpringBootTestContextBootstrapper
        extends SpringBootTestContextBootstrapper
        implements SmartCloud {
    static {
        System.setProperty("ebean.registerShutdownHook", Boolean.FALSE.toString());
    }

    private final Map services = new HashMap<>();
    private final LazyInitializer props = new LazyInitializer() {
        @Override
        protected T initialize() throws ConcurrentException {
            try {
                return createProps();
            } catch (Exception err) {
                throw new ConcurrentException(err);
            }
        }
    };

    @Override
    protected ContextLoader resolveContextLoader(Class testClass, List configAttributesList) {
        return new SpringBootContextLoader() {
            @Override
            protected SpringApplication getSpringApplication() {
                for (;;) {
                    try {
                        T delegate = props.get();

                        //
                        // ~ pass as property and let cloud connector to pick up it via property
                        //
                        for (ServiceInfo info : services.values()) {
                            String uri = null;
                            if (info instanceof UriBasedServiceInfo) {
                                uri = ((UriBasedServiceInfo) info).getUri();
                            } else if (info instanceof RawServiceInfo raw) {
                                uri = raw.toByteSource().asCharSource(StandardCharsets.UTF_8).read();
                            } else {
                                throw new IllegalArgumentException();
                            }
                            delegate.cfg().setLocalProperty(String.format("service.%s.uri", info.getId()), uri);
                        }

                        return new ConfigurableApplicationBootstrap(delegate);
                    } catch (Throwable err) {
                        ExceptionUtils.wrapAndThrow(err);
                    }
                }
            }
        };
    }
    protected abstract T createProps() throws Exception;

    @Override
    public void addUps(ServiceInfo info) {
        services.put(info.getId(), info);
    }
    @Override
    public boolean removeUps(String id) {
        if (props.isInitialized()) {
            try {
                T delegate = props.get();
                ApplicationConfig cfg = delegate.cfg();
                cfg.clearLocalProperty(String.format("service.%s.uri", id));
                return Objects.nonNull(services.remove(id));
            } catch (ConcurrentException err) {
                ExceptionUtils.wrapAndThrow(err);
            }
        }
        return false;
    }
    public static RawServiceInfo genRawServiceInfo(String id) throws Exception {
        byte[] data = new byte[64];
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.nextBytes(data);
        return new RawServiceInfo(id, data);
    }

    private static class ConfigurableApplicationBootstrap extends AbstractBootstrap {
        protected ConfigurableApplicationBootstrap(T props) throws Throwable {
            super(props);
        }
        @Override
        protected void applyInitializers(ConfigurableApplicationContext context) {
            super.applyInitializers(context);

            if (context.containsBean(EmbeddedKafkaBroker.BEAN_NAME)) {
                EmbeddedKafkaZKBroker broker = (EmbeddedKafkaZKBroker) context.getBeanFactory().getSingleton(EmbeddedKafkaBroker.BEAN_NAME);
                if (Objects.nonNull(broker)) {
                    if (Objects.nonNull(broker.getBrokerAddresses())) {
                        BrokerAddress address = Iterables.getOnlyElement(Arrays.asList(broker.getBrokerAddresses()));
                        KafkaServiceInfo ksi = new KafkaServiceInfo(HostAndPort.fromParts(address.getHost(), address.getPort()));
                        addUps(ksi);
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy