Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way to configure server for a plugin #883

Merged
merged 7 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2023 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.it;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.linecorp.armeria.common.AggregatedHttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension;

final class AllReplicasPluginTest {

@RegisterExtension
static final CentralDogmaExtension dogma = new CentralDogmaExtension();

@Test
void hello() {
// hello service is registered by TestAllReplicasPlugin.
final AggregatedHttpResponse res = dogma.httpClient().get("/hello").aggregate().join();
assertThat(res.status()).isSameAs(HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2023 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.it;

import java.util.concurrent.CompletionStage;

import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.util.UnmodifiableFuture;
import com.linecorp.centraldogma.server.plugin.AllReplicasPlugin;
import com.linecorp.centraldogma.server.plugin.PluginContext;
import com.linecorp.centraldogma.server.plugin.PluginInitContext;

public final class TestAllReplicasPlugin extends AllReplicasPlugin {

@Override
public void init(PluginInitContext pluginInitContext) {
pluginInitContext.serverBuilder()
.service("/hello", (ctx, req) -> HttpResponse.of("Hello, world!"));
}

@Override
public CompletionStage<Void> start(PluginContext context) {
return UnmodifiableFuture.completedFuture(null);
}

@Override
public CompletionStage<Void> stop(PluginContext context) {
return UnmodifiableFuture.completedFuture(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.linecorp.centraldogma.it.TestAllReplicasPlugin
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@
import com.linecorp.centraldogma.server.internal.thrift.TokenlessClientLogger;
import com.linecorp.centraldogma.server.metadata.MetadataService;
import com.linecorp.centraldogma.server.metadata.MetadataServiceInjector;
import com.linecorp.centraldogma.server.plugin.AllReplicasPlugin;
import com.linecorp.centraldogma.server.plugin.Plugin;
import com.linecorp.centraldogma.server.plugin.PluginInitContext;
import com.linecorp.centraldogma.server.plugin.PluginTarget;
import com.linecorp.centraldogma.server.storage.project.ProjectManager;

Expand Down Expand Up @@ -364,7 +366,7 @@ private void doStart() throws Exception {
}

logger.info("Starting the RPC server.");
server = startServer(pm, executor, meterRegistry, sessionManager);
server = startServer(pm, executor, purgeWorker, meterRegistry, sessionManager);
logger.info("Started the RPC server at: {}", server.activePorts());
logger.info("Started the Central Dogma successfully.");
success = true;
Expand Down Expand Up @@ -489,7 +491,8 @@ private SessionManager initializeSessionManager() throws Exception {
}

private Server startServer(ProjectManager pm, CommandExecutor executor,
MeterRegistry meterRegistry, @Nullable SessionManager sessionManager) {
ScheduledExecutorService purgeWorker, MeterRegistry meterRegistry,
@Nullable SessionManager sessionManager) {
final ServerBuilder sb = Server.builder();
sb.verboseResponses(true);
cfg.ports().forEach(sb::port);
Expand Down Expand Up @@ -558,6 +561,18 @@ private Server startServer(ProjectManager pm, CommandExecutor executor,
sb.accessLogFormat(accessLogFormat);
}

if (pluginsForAllReplicas != null) {
final PluginInitContext pluginInitContext =
new PluginInitContext(config(), pm, executor, meterRegistry, purgeWorker, sb);
pluginsForAllReplicas.plugins()
.forEach(p -> {
if (!(p instanceof AllReplicasPlugin)) {
return;
}
final AllReplicasPlugin plugin = (AllReplicasPlugin) p;
plugin.init(pluginInitContext);
});
}
// Configure the uncaught exception handler just before starting the server so that override the
// default exception handler set by third-party libraries such as NIOServerCnxnFactory.
Thread.setDefaultUncaughtExceptionHandler((t, e) -> logger.warn("Uncaught exception: {}", t, e));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2023 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.server.plugin;

/**
* A Base class for {@link Plugin} whose {@link #target()} is {@link PluginTarget#ALL_REPLICAS}.
*/
public abstract class AllReplicasPlugin implements Plugin {

/**
* Overrides this method to initialize the plugin using the {@link PluginInitContext}.
*/
public void init(PluginInitContext pluginInitContext) {}

Check warning on line 26 in server/src/main/java/com/linecorp/centraldogma/server/plugin/AllReplicasPlugin.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/linecorp/centraldogma/server/plugin/AllReplicasPlugin.java#L26

Added line #L26 was not covered by tests

@Override
public final PluginTarget target() {
return PluginTarget.ALL_REPLICAS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
import com.linecorp.centraldogma.server.CentralDogmaConfig;

/**
* An interface which defines callbacks for a plug-in.
* An interface which defines callbacks for a plug-in. If you want to initialize a {@link Plugin} by configuring
* the Central Dogma server (e.g. adding a service for your plugin), use {@link AllReplicasPlugin}.
*/
public interface Plugin {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
/**
* A class which is used to pass internally-created instances into the {@link Plugin}.
*/
public final class PluginContext {
public class PluginContext {

private final CentralDogmaConfig config;
private final ProjectManager projectManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2023 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.server.plugin;

import static java.util.Objects.requireNonNull;

import java.util.concurrent.ScheduledExecutorService;

import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.centraldogma.server.CentralDogmaConfig;
import com.linecorp.centraldogma.server.command.CommandExecutor;
import com.linecorp.centraldogma.server.storage.project.ProjectManager;

import io.micrometer.core.instrument.MeterRegistry;

/**
* A context that is used to pass when calling {@link AllReplicasPlugin#init(PluginInitContext)}.
*/
public final class PluginInitContext extends PluginContext {

private final ServerBuilder serverBuilder;

/**
* Creates a new instance.
*/
public PluginInitContext(CentralDogmaConfig config,
ProjectManager projectManager,
CommandExecutor commandExecutor,
MeterRegistry meterRegistry,
ScheduledExecutorService purgeWorker,
ServerBuilder serverBuilder) {
super(config, projectManager, commandExecutor, meterRegistry, purgeWorker);
this.serverBuilder = requireNonNull(serverBuilder, "serverBuilder");
}

/**
* Returns the {@link ServerBuilder} of the Central Dogma server.
*/
public ServerBuilder serverBuilder() {
return serverBuilder;
}
}