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 5 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 @@ -558,6 +560,18 @@ private Server startServer(ProjectManager pm, CommandExecutor executor,
sb.accessLogFormat(accessLogFormat);
}

if (pluginsForAllReplicas != null) {
final PluginInitContext pluginInitContext = new PluginInitContext(config(), sb);
pluginsForAllReplicas.plugins()
.forEach(p -> {
if (!(p instanceof AllReplicasPlugin)) {
return;
}
final AllReplicasPlugin plugin = (AllReplicasPlugin) p;
plugin.init(pluginInitContext);
});
}

final Server s = sb.build();
s.start().join();
return s;
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
@@ -0,0 +1,53 @@
/*
* 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 com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.centraldogma.server.CentralDogmaConfig;

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question) I was thinking we would need at least ProjectManager, CommandExecutor will be needed to build services which can write to CentralDogma storage. Is there no need for these values? (it looks like they are available at init time).

I actually expect we may also want access to MeterRegistry, and actually all values in PluginContext eventually.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I thought somehow they are not created when the init method is called. 😅
Let me fix that. 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. PTAL. 😉


private final CentralDogmaConfig config;
private final ServerBuilder serverBuilder;

/**
* Creates a new instance.
*/
public PluginInitContext(CentralDogmaConfig config, ServerBuilder serverBuilder) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public PluginInitContext(CentralDogmaConfig config, ServerBuilder serverBuilder) {
PluginInitContext(CentralDogmaConfig config, ServerBuilder serverBuilder) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I cannot remove the public modifier because the class is in a different package.

this.config = requireNonNull(config, "config");
this.serverBuilder = requireNonNull(serverBuilder, "serverBuilder");
}

/**
* Returns the {@link CentralDogmaConfig}.
*/
public CentralDogmaConfig config() {
return config;

Check warning on line 44 in server/src/main/java/com/linecorp/centraldogma/server/plugin/PluginInitContext.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/linecorp/centraldogma/server/plugin/PluginInitContext.java#L44

Added line #L44 was not covered by tests
}

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