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

com.linecorp.centraldogma.testing.CentralDogmaRule Maven / Gradle / Ivy

/*
 * Copyright 2017 LINE Corporation
 *
 * LINE Corporation 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:
 *
 *   https://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.linecorp.centraldogma.testing;

import java.io.IOError;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import javax.annotation.Nullable;

import org.junit.Rule;
import org.junit.rules.TemporaryFolder;

import com.spotify.futures.CompletableFutures;

import com.linecorp.armeria.client.ClientFactoryBuilder;
import com.linecorp.armeria.client.HttpClient;
import com.linecorp.armeria.common.SessionProtocol;
import com.linecorp.armeria.common.util.Exceptions;
import com.linecorp.armeria.server.ServerPort;
import com.linecorp.centraldogma.client.CentralDogma;
import com.linecorp.centraldogma.client.armeria.AbstractArmeriaCentralDogmaBuilder;
import com.linecorp.centraldogma.client.armeria.ArmeriaCentralDogmaBuilder;
import com.linecorp.centraldogma.client.armeria.legacy.LegacyCentralDogmaBuilder;
import com.linecorp.centraldogma.server.CentralDogmaBuilder;
import com.linecorp.centraldogma.server.GracefulShutdownTimeout;
import com.linecorp.centraldogma.server.MirroringService;
import com.linecorp.centraldogma.server.TlsConfig;

import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.util.NetUtil;

/**
 * JUnit {@link Rule} that starts an embedded Central Dogma server.
 *
 * 
{@code
 * > public class MyTest {
 * >     @ClassRule
 * >     public static final CentralDogmaRule rule = new CentralDogmaRule();
 * >
 * >     @Test
 * >     public void test() throws Exception {
 * >         CentralDogma dogma = rule.client();
 * >         dogma.push(...).join();
 * >         ...
 * >     }
 * > }
 * }
*/ public class CentralDogmaRule extends TemporaryFolder { private static final InetSocketAddress TEST_PORT = new InetSocketAddress(NetUtil.LOCALHOST4, 0); private final boolean useTls; @Nullable private volatile com.linecorp.centraldogma.server.CentralDogma dogma; @Nullable private volatile CentralDogma client; @Nullable private volatile CentralDogma legacyClient; @Nullable private volatile HttpClient httpClient; @Nullable private volatile InetSocketAddress serverAddress; public CentralDogmaRule() { this(false); } public CentralDogmaRule(boolean useTls) { this.useTls = useTls; } /** * Returns whether the server is running over TLS or not. */ public boolean useTls() { return useTls; } /** * Returns the server. * * @throws IllegalStateException if Central Dogma did not start yet */ public final com.linecorp.centraldogma.server.CentralDogma dogma() { final com.linecorp.centraldogma.server.CentralDogma dogma = this.dogma; if (dogma == null) { throw new IllegalStateException("Central Dogma not available"); } return dogma; } /** * Returns the {@link MirroringService} of the server. * * @throws IllegalStateException if Central Dogma did not start yet */ public final MirroringService mirroringService() { return dogma().mirroringService().get(); } /** * Returns the HTTP-based {@link CentralDogma} client. * * @throws IllegalStateException if Central Dogma did not start yet */ public final CentralDogma client() { final CentralDogma client = this.client; if (client == null) { throw new IllegalStateException("Central Dogma client not available"); } return client; } /** * Returns the Thrift-based {@link CentralDogma} client. * * @throws IllegalStateException if Central Dogma did not start yet */ public final CentralDogma legacyClient() { final CentralDogma legacyClient = this.legacyClient; if (legacyClient == null) { throw new IllegalStateException("Central Dogma not started"); } return legacyClient; } /** * Returns the HTTP client. * * @throws IllegalStateException if Central Dogma did not start yet */ public final HttpClient httpClient() { final HttpClient httpClient = this.httpClient; if (httpClient == null) { throw new IllegalStateException("Central Dogma not started"); } return httpClient; } /** * Returns the server address. * * @throws IllegalStateException if Central Dogma did not start yet */ public final InetSocketAddress serverAddress() { final InetSocketAddress serverAddress = this.serverAddress; if (serverAddress == null) { throw new IllegalStateException("Central Dogma not started"); } return serverAddress; } /** * Starts an embedded server with {@link #start()} and calls {@link #scaffold(CentralDogma)}. */ @Override protected void before() throws Throwable { super.before(); start(); final CentralDogma client = this.client; assert client != null; assert legacyClient != null; scaffold(client); } /** * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server. * Note that you don't need to call this method if you did not stop the server with {@link #stop()}, * because the server is automatically started up by JUnit. */ public final void start() { startAsync().join(); } /** * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server * asynchronously. */ public final CompletableFuture startAsync() { // Create the root folder first if not. try { getRoot(); } catch (IllegalStateException unused) { try { create(); } catch (IOException e) { return CompletableFutures.exceptionallyCompletedFuture(e); } } final CentralDogmaBuilder builder = new CentralDogmaBuilder(getRoot()) .port(TEST_PORT, useTls ? SessionProtocol.HTTPS : SessionProtocol.HTTP) .webAppEnabled(false) .mirroringEnabled(false) .gracefulShutdownTimeout(new GracefulShutdownTimeout(0, 0)); if (useTls) { try { final SelfSignedCertificate ssc = new SelfSignedCertificate(); builder.tls(new TlsConfig(ssc.certificate(), ssc.privateKey(), null)); } catch (Exception e) { Exceptions.throwUnsafely(e); } } configure(builder); final com.linecorp.centraldogma.server.CentralDogma dogma = builder.build(); this.dogma = dogma; return dogma.start().thenRun(() -> { final Optional activePort = dogma.activePort(); if (!activePort.isPresent()) { // Stopped already. return; } final InetSocketAddress serverAddress = activePort.get().localAddress(); this.serverAddress = serverAddress; final ArmeriaCentralDogmaBuilder clientBuilder = new ArmeriaCentralDogmaBuilder(); final LegacyCentralDogmaBuilder legacyClientBuilder = new LegacyCentralDogmaBuilder(); configureClientCommon(clientBuilder); configureClientCommon(legacyClientBuilder); configureClient(clientBuilder); configureClient(legacyClientBuilder); try { client = clientBuilder.build(); legacyClient = legacyClientBuilder.build(); } catch (UnknownHostException e) { // Should never reach here. throw new IOError(e); } httpClient = HttpClient.of( "h2c://" + serverAddress.getHostString() + ':' + serverAddress.getPort()); }); } private void configureClientCommon(AbstractArmeriaCentralDogmaBuilder builder) { final InetSocketAddress serverAddress = this.serverAddress; assert serverAddress != null; builder.host(serverAddress.getHostString(), serverAddress.getPort()); if (useTls) { builder.useTls(); builder.clientFactory( new ClientFactoryBuilder().sslContextCustomizer( b -> b.trustManager(InsecureTrustManagerFactory.INSTANCE)).build()); } } /** * Override this method to configure the server. */ protected void configure(CentralDogmaBuilder builder) {} /** * Override this method to configure the HTTP-based {@link CentralDogma} client builder. */ protected void configureClient(ArmeriaCentralDogmaBuilder builder) {} /** * Override this method to configure the Thrift-based {@link CentralDogma} client builder. */ protected void configureClient(LegacyCentralDogmaBuilder builder) {} /** * Override this method to perform the initial updates on the server, such as creating a repository and * populating sample data. */ protected void scaffold(CentralDogma client) {} /** * Stops the server and deletes the temporary files created by the server. */ @Override protected void after() { stopAsync().whenComplete((unused1, unused2) -> delete()); } /** * Stops the server and deletes the temporary files created by the server. Note that you don't usually need * to call this method manually because the server is automatically stopped at the end by JUnit. */ public final void stop() { stopAsync().join(); } /** * Stops the server and deletes the temporary files created by the server. Note that you don't usually need * to call this method manually because the server is automatically stopped at the end by JUnit. */ public final CompletableFuture stopAsync() { final com.linecorp.centraldogma.server.CentralDogma dogma = this.dogma; this.dogma = null; if (dogma != null) { return dogma.stop(); } else { return CompletableFuture.completedFuture(null); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy