Skip to content

Commit

Permalink
feat: core refactoring to handle extension provider
Browse files Browse the repository at this point in the history
  • Loading branch information
fhussonnois committed Jan 3, 2025
1 parent f770994 commit 708e357
Show file tree
Hide file tree
Showing 253 changed files with 5,076 additions and 4,455 deletions.
130 changes: 65 additions & 65 deletions cli/src/main/java/io/streamthoughts/jikkou/client/Jikkou.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,32 @@
* The main-class
*/
@Command(name = "jikkou",
descriptionHeading = "%n%n",
parameterListHeading = "%nParameters:%n%n",
optionListHeading = "%nOPTIONS:%n%n",
commandListHeading = "%nCommands:%n%n",
headerHeading = "Usage: ",
synopsisHeading = "%n",
description = "Jikkou CLI:: A command-line client designed to provide an efficient and easy way to manage, automate, and provision resources. %n%nFind more information at: https://www.jikkou.io/.",
mixinStandardHelpOptions = true,
versionProvider = Jikkou.ResourcePropertiesVersionProvider.class,
subcommands = {
CreateResourceCommand.class,
DeleteResourceCommand.class,
UpdateResourceCommand.class,
ApplyResourceCommand.class,
PatchResourceCommand.class,
ApiExtensionCommand.class,
ListApiResourcesCommand.class,
ConfigCommand.class,
DiffCommand.class,
PrepareCommand.class,
ValidateCommand.class,
HealthCommand.class,
CommandLine.HelpCommand.class,
AutoComplete.GenerateCompletion.class,
ContextNamesCompletionCandidateCommand.class
}
descriptionHeading = "%n%n",
parameterListHeading = "%nParameters:%n%n",
optionListHeading = "%nOPTIONS:%n%n",
commandListHeading = "%nCommands:%n%n",
headerHeading = "Usage: ",
synopsisHeading = "%n",
description = "Jikkou CLI:: A command-line client designed to provide an efficient and easy way to manage, automate, and provision resources. %n%nFind more information at: https://www.jikkou.io/.",
mixinStandardHelpOptions = true,
versionProvider = Jikkou.ResourcePropertiesVersionProvider.class,
subcommands = {
CreateResourceCommand.class,
DeleteResourceCommand.class,
UpdateResourceCommand.class,
ApplyResourceCommand.class,
PatchResourceCommand.class,
ApiExtensionCommand.class,
ListApiResourcesCommand.class,
ConfigCommand.class,
DiffCommand.class,
PrepareCommand.class,
ValidateCommand.class,
HealthCommand.class,
CommandLine.HelpCommand.class,
AutoComplete.GenerateCompletion.class,
ContextNamesCompletionCandidateCommand.class
}
)
@Singleton
public final class Jikkou {
Expand All @@ -109,20 +109,20 @@ public void onStartupEvent(StartupEvent event) {
ConfigurationContext configurationContext = GlobalConfigurationContext.getConfigurationContext();
if (!configurationContext.isExists()) {
System.err.printf(
"No configuration context has been defined (file:%s)." +
" Run 'jikkou config set-context <context_name> --config-props=kafka.client.bootstrap.servers=localhost:9092" +
" [--config-props=<config_string>] [--config-file=<config_file>].' to create a context.%n",
configurationContext.getConfigFile());
"No configuration context has been defined (file:%s)." +
" Run 'jikkou config set-context <context_name>" +
" [--config-props=<config_string>] [--config-file=<config_file>].' to create a context.%n",
configurationContext.getConfigFile());
}
}

public static void main(final String... args) {
Logging.configureRootLoggerLevel();
var printer = BannerPrinterBuilder.newBuilder()
.setLogger(LOG)
.setLoggerLevel(Level.INFO)
.setMode(Banner.Mode.LOG)
.build();
.setLogger(LOG)
.setLoggerLevel(Level.INFO)
.setMode(Banner.Mode.LOG)
.build();
printer.print(new JikkouBanner());

System.exit(execute(args));
Expand Down Expand Up @@ -154,24 +154,24 @@ private int executionStrategy(CommandLine.ParseResult parseResult) {
private static CommandLine createCommandLine(ApplicationContext context) {
Jikkou app = context.getBean(Jikkou.class);
final CommandLine commandLine = new CommandLine(app, new MicronautFactory(context))
.setCaseInsensitiveEnumValuesAllowed(true)
.setUsageHelpWidth(160)
.setExecutionStrategy(app::executionStrategy)
.setExecutionExceptionHandler((ex, cmd, parseResult) -> {
final PrintWriter err = cmd.getErr();
if (!(ex instanceof JikkouRuntimeException)) {
err.println(cmd.getColorScheme().stackTraceText(ex));
}
err.println(cmd.getColorScheme().errorText(String.format("Error: %s: %s",
ex.getClass().getSimpleName(),
ex.getLocalizedMessage()
)));
if (ex instanceof InvalidResourceFileException) {
return CommandLine.ExitCode.USAGE;
}
return cmd.getCommandSpec().exitCodeOnExecutionException();
})
.setParameterExceptionHandler(new ShortErrorMessageHandler());
.setCaseInsensitiveEnumValuesAllowed(true)
.setUsageHelpWidth(160)
.setExecutionStrategy(app::executionStrategy)
.setExecutionExceptionHandler((ex, cmd, parseResult) -> {
final PrintWriter err = cmd.getErr();
if (!(ex instanceof JikkouRuntimeException)) {
err.println(cmd.getColorScheme().stackTraceText(ex));
}
err.println(cmd.getColorScheme().errorText(String.format("Error: %s: %s",
ex.getClass().getSimpleName(),
ex.getLocalizedMessage()
)));
if (ex instanceof InvalidResourceFileException) {
return CommandLine.ExitCode.USAGE;
}
return cmd.getCommandSpec().exitCodeOnExecutionException();
})
.setParameterExceptionHandler(new ShortErrorMessageHandler());

Optional<JikkouApiClient> optionalApiClient = context.findBean(JikkouApiClient.class);
// NOT IN PROXY-MODE
Expand All @@ -184,15 +184,15 @@ private static CommandLine createCommandLine(ApplicationContext context) {
try {
Info info = client.getServerInfo();
LOG.info("Connected to Jikkou API server (version: %{}, buildTimestamp: {}, commitId: {}).",
info.version(),
info.buildTimestamp(),
info.commitId()
info.version(),
info.buildTimestamp(),
info.commitId()
);
} catch (Exception e) {
final PrintWriter err = commandLine.getErr();
err.println(commandLine.getColorScheme().errorText(String.format("Error: %s. Cause: %s",
"Failed to connect to Jikkou API server",
e.getLocalizedMessage()
"Failed to connect to Jikkou API server",
e.getLocalizedMessage()
)));
isApiEnabled = false; // DISABLE API
}
Expand Down Expand Up @@ -256,11 +256,11 @@ public static CommandLine.IHelpSectionRenderer buildHelpSectionRenderer(boolean
additional.add("help");

sections.put("%nCORE COMMANDS:%n",
core.stream().sorted(Comparator.comparing(Function.identity())).toList());
core.stream().sorted(Comparator.comparing(Function.identity())).toList());
sections.put("%nSYSTEM MANAGEMENT COMMANDS:%n",
system.stream().sorted(Comparator.comparing(Function.identity())).toList());
system.stream().sorted(Comparator.comparing(Function.identity())).toList());
sections.put("%nADDITIONAL COMMANDS:%n",
additional.stream().sorted(Comparator.comparing(Function.identity())).toList());
additional.stream().sorted(Comparator.comparing(Function.identity())).toList());

return new CommandGroupRenderer(sections);
}
Expand All @@ -277,7 +277,7 @@ public int handleParseException(final CommandLine.ParameterException ex,
PrintWriter err = cmd.getErr();

// if tracing at DEBUG level, show the location of the issue
if ("DEBUG".equalsIgnoreCase(System.getProperty("picocli.trace"))) {
if ("DEBUG" .equalsIgnoreCase(System.getProperty("picocli.trace"))) {
err.println(cmd.getColorScheme().stackTraceText(ex));
}

Expand All @@ -287,8 +287,8 @@ public int handleParseException(final CommandLine.ParameterException ex,
cmd.usage(err);
err.printf("%nSee '%s --help' for more information about a command.%n", spec.qualifiedName());
return cmd.getExitCodeExceptionMapper() != null
? cmd.getExitCodeExceptionMapper().getExitCode(ex)
: spec.exitCodeOnInvalidInput();
? cmd.getExitCodeExceptionMapper().getExitCode(ex)
: spec.exitCodeOnInvalidInput();
}
}

Expand All @@ -303,8 +303,8 @@ static class ResourcePropertiesVersionProvider implements CommandLine.IVersionPr

public String[] getVersion() {
return new String[]{
"Jikkou version \"" + JikkouInfo.getVersion() + "\" " + JikkouInfo.getBuildTimestamp(),
"JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})"
"Jikkou version \"" + JikkouInfo.getVersion() + "\" " + JikkouInfo.getBuildTimestamp(),
"JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})"
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,14 @@ public final class BeanFactory {
@Singleton
public ExtensionDescriptorRegistry extensionDescriptorRegistry() {
return new DefaultExtensionRegistry(
new DefaultExtensionDescriptorFactory(),
new ClassExtensionAliasesGenerator()
new DefaultExtensionDescriptorFactory(),
new ClassExtensionAliasesGenerator()
);
}

@Singleton
public ExtensionFactory extensionFactory(Configuration configuration,
ExtensionDescriptorRegistry registry) {
return new DefaultExtensionFactory(
registry,
configuration
);
public ExtensionFactory extensionFactory(ExtensionDescriptorRegistry registry) {
return new DefaultExtensionFactory(registry);
}

@Singleton
Expand All @@ -68,15 +64,16 @@ public JikkouContext jikkouContext(Configuration configuration,
public ResourceRegistry resourceRegistry() {
return new DefaultResourceRegistry();
}

@Singleton
@SuppressWarnings({"rawtypes", "unchecked"})
public JikkouApi jikkouApi(JikkouContext context,
ExtensionDescriptorRegistry registry,
JikkouApi.ApiBuilder apiBuilder) {
ApiConfigurator[] configurators = {
new ValidationApiConfigurator(registry),
new TransformationApiConfigurator(registry),
new ChangeReporterApiConfigurator(registry)
new ValidationApiConfigurator(registry),
new TransformationApiConfigurator(registry),
new ChangeReporterApiConfigurator(registry)
};
return context.createApi(apiBuilder, configurators);
}
Expand Down Expand Up @@ -106,8 +103,8 @@ public ResourceWriter defaultResourceWriter() {
@Singleton
public ResourceLoaderFacade resourceLoaderFacade(Configuration configuration) {
ResourceTemplateRenderer renderer = new JinjaResourceTemplateRenderer()
.withPreserveRawTags(false)
.withFailOnUnknownTokens(false);
.withPreserveRawTags(false)
.withFailOnUnknownTokens(false);
renderer.configure(configuration);
return new ResourceLoaderFacade(renderer, Jackson.YAML_OBJECT_MAPPER);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,60 +34,60 @@ public final class ProxyApiFactory {
public JikkouApiClient apiClient() {
ApiClientBuilder builder = ApiClientBuilder.builder();
builder
.withBasePath(configuration.url())
.withDebugging(configuration.debugging())
.withWriteTimeout(getWriteTimeout())
.withReadTimeout(getReadTimeout())
.withConnectTimeout(getConnectionTimeout());
.withBasePath(configuration.url())
.withDebugging(configuration.debugging())
.withWriteTimeout(getWriteTimeout())
.withReadTimeout(getReadTimeout())
.withConnectTimeout(getConnectionTimeout());

ProxyConfiguration.Security security = configuration.security();

// Bearer Token based authentication.
security.accessToken()
.ifPresent(accessToken ->
builder.withAuthenticator(
new BearerTokenAuthenticator(() -> new BearerToken(accessToken))
)
);
.ifPresent(accessToken ->
builder.withAuthenticator(
new BearerTokenAuthenticator(() -> new BearerToken(accessToken))
)
);
// UsernamePassword based authentication.
Optional.ofNullable(security.basicAuth())
.ifPresent(basicAuth -> {
Optional<String> username = basicAuth.username();
Optional<String> password = basicAuth.password();
if (username.isPresent() && password.isPresent()) {
builder.withAuthenticator(new UsernamePasswordAuthenticator(() -> {
return new UsernamePasswordCredential(
username.get(),
password.get()
);
}));
}
});
.ifPresent(basicAuth -> {
Optional<String> username = basicAuth.username();
Optional<String> password = basicAuth.password();
if (username.isPresent() && password.isPresent()) {
builder.withAuthenticator(new UsernamePasswordAuthenticator(() -> {
return new UsernamePasswordCredential(
username.get(),
password.get()
);
}));
}
});

return new DefaultJikkouApiClient(builder.build());
}

@Singleton
@SuppressWarnings("rawtypes")
public JikkouApi.ApiBuilder proxyApiBuilder(JikkouContext context, JikkouApiClient apiClient) {
return new JikkouApiProxy.Builder(context.getExtensionFactory(), apiClient);
return new JikkouApiProxy.Builder(context.getExtensionFactory(), context.getResourceRegistry(), apiClient);
}

@NotNull
private Integer getConnectionTimeout() {
return configuration.connectTimeout()
.orElse(configuration.defaultTimeout());
.orElse(configuration.defaultTimeout());
}

@NotNull
private Integer getReadTimeout() {
return configuration.readTimeout()
.orElse(configuration.defaultTimeout());
.orElse(configuration.defaultTimeout());
}

@NotNull
private Integer getWriteTimeout() {
return configuration.writeTimeout()
.orElse(configuration.defaultTimeout());
.orElse(configuration.defaultTimeout());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
import io.streamthoughts.jikkou.core.JikkouApi;
import io.streamthoughts.jikkou.core.config.Configuration;
import io.streamthoughts.jikkou.core.io.writer.ResourceWriter;
import io.streamthoughts.jikkou.core.models.DefaultResourceListObject;
import io.streamthoughts.jikkou.core.models.HasMetadata;
import io.streamthoughts.jikkou.core.models.ResourceListObject;
import io.streamthoughts.jikkou.core.models.ResourceList;
import io.streamthoughts.jikkou.core.models.ResourceType;
import jakarta.inject.Inject;
import java.io.ByteArrayOutputStream;
import java.util.List;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
Expand Down Expand Up @@ -69,7 +67,7 @@ public GetResourceCommand() {
**/
@Override
public Integer call() throws Exception {
ResourceListObject<HasMetadata> resources;
ResourceList<HasMetadata> resources;
if (Strings.isBlank(name)) {
resources = api.listResources(
type,
Expand All @@ -82,7 +80,7 @@ public Integer call() throws Exception {
name,
Configuration.from(options())
);
resources = new DefaultResourceListObject<>(List.of(resource));
resources = ResourceList.of(resource);
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
if (list) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import io.streamthoughts.jikkou.core.models.ApiValidationResult;
import io.streamthoughts.jikkou.core.models.HasItems;
import io.streamthoughts.jikkou.core.models.HasMetadata;
import io.streamthoughts.jikkou.core.models.ResourceListObject;
import io.streamthoughts.jikkou.core.models.ResourceList;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -66,7 +66,7 @@ public class ValidateCommand extends CLIBaseCommand implements Callable<Integer>
public Integer call() throws IOException {
ApiValidationResult result = api.validate(getResources(), getReconciliationContext());
if (result.isValid()) {
ResourceListObject<HasMetadata> resources = result.get();
ResourceList<HasMetadata> resources = result.get();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
writer.write(formatOptions.format(), resources.getItems(), baos);
System.out.println(baos);
Expand Down
Loading

0 comments on commit 708e357

Please sign in to comment.