Skip to content

Commit

Permalink
Fixed "use-config" when Kafkactl config is overrided by KAFKACTL_CONF…
Browse files Browse the repository at this point in the history
…IG (#27)

* Fixed use config when Kafkactl config is override by var env

* Update get config directory

* Update get config directory

* Update get config directory

* Update get config directory

* Update get config directory

* Update get config directory

* Update unit tests

* Update unit tests

* Update unit tests

* Update unit tests

* Update unit tests set property

* Update readme
  • Loading branch information
Loïc GREFFIER authored Mar 9, 2023
1 parent a583a64 commit 77eb403
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 29 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,19 @@ Kafkactl requires 3 variables to work:

These variable can be defined in the dedicated configuration file.

Create a folder .kafkactl in your home directory:
Create a `.kafkactl/config.yml` file in your home directory:

- Windows: C:\Users\Name\\.kafkactl
- Linux: ~/.kafkactl
- Windows: C:\Users\Name\\.kafkactl\config.yml
- Linux: ~/.kafkactl/config.yml

Create .kafkactl/config.yml with the following content:
It is possible to override this default location by setting the **KAFKACTL_CONFIG** environment variable:

```console
KAFKACTL_CONFIG=C:\AnotherDirectory\config.yml
KAFKACTL_CONFIG=/anotherDirectory/config.yml
```

Fill the config.yml file with the following content:

```yaml
kafkactl:
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/com/michelin/kafkactl/KafkactlCommand.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.michelin.kafkactl;

import com.michelin.kafkactl.services.SystemService;
import com.michelin.kafkactl.utils.VersionProvider;
import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.core.util.StringUtils;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.util.Optional;
import java.util.concurrent.Callable;

import static com.michelin.kafkactl.KafkactlConfig.KAFKACTL_CONFIG;

@Command(name = "kafkactl",
subcommands = {
ApiResourcesSubcommand.class,
Expand Down Expand Up @@ -55,11 +59,11 @@ public class KafkactlCommand implements Callable<Integer> {
*/
public static void main(String[] args) {
if (System.getenv().keySet().stream().noneMatch(s -> s.startsWith("KAFKACTL_"))) {
System.setProperty("micronaut.config.files", System.getProperty("user.home") + "/.kafkactl/config.yml");
SystemService.setProperty("micronaut.config.files", SystemService.getProperty("user.home") + "/.kafkactl/config.yml");
}

if (System.getenv("KAFKACTL_CONFIG") != null) {
System.setProperty("micronaut.config.files", System.getenv("KAFKACTL_CONFIG"));
if (StringUtils.isNotEmpty(SystemService.getEnv(KAFKACTL_CONFIG))) {
SystemService.setProperty("micronaut.config.files", SystemService.getEnv(KAFKACTL_CONFIG));
}

int exitCode = PicocliRunner.execute(KafkactlCommand.class, args);
Expand Down
29 changes: 26 additions & 3 deletions src/main/java/com/michelin/kafkactl/KafkactlConfig.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package com.michelin.kafkactl;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.michelin.kafkactl.services.SystemService;
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.ReflectiveAccess;
import io.micronaut.core.convert.format.MapFormat;
import io.micronaut.core.util.StringUtils;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.io.File;
import java.util.List;
import java.util.Map;

Expand All @@ -18,8 +19,8 @@
@Introspected
@ConfigurationProperties("kafkactl")
public class KafkactlConfig {
public static final String KAFKACTL_CONFIG = "KAFKACTL_CONFIG";
private String version;
private String configPath;
private String api;
private String userToken;
private String currentNamespace;
Expand Down Expand Up @@ -48,4 +49,26 @@ public static class ApiContext {
private String namespace;
}
}

/**
* Get the current user config directory
* @return The config directory
*/
public String getConfigDirectory() {
if (StringUtils.isNotEmpty(SystemService.getEnv(KAFKACTL_CONFIG))) {
String parent = new File(SystemService.getEnv(KAFKACTL_CONFIG)).getParent();
return parent != null ? parent : ".";
}

return SystemService.getProperty("user.home") + "/.kafkactl";
}

/**
* Get the current user config full path
* @return The config path
*/
public String getConfigPath() {
return StringUtils.isNotEmpty(SystemService.getEnv(KAFKACTL_CONFIG)) ?
SystemService.getEnv(KAFKACTL_CONFIG) : SystemService.getProperty("user.home") + "/.kafkactl/config.yml";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Optional<KafkactlConfig.Context> getContextByName(String name) {
*/
public void updateConfigurationContext(KafkactlConfig.Context contextToSet) throws IOException {
Yaml yaml = new Yaml();
File initialFile = new File(kafkactlConfig.getConfigPath() + "/config.yml");
File initialFile = new File(kafkactlConfig.getConfigPath());
InputStream targetStream = new FileInputStream(initialFile);
Map<String, LinkedHashMap<String, Object>> rootNodeConfig = yaml.load(targetStream);

Expand All @@ -69,7 +69,7 @@ public void updateConfigurationContext(KafkactlConfig.Context contextToSet) thro
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);

Yaml yamlMapper = new Yaml(options);
FileWriter writer = new FileWriter(kafkactlConfig.getConfigPath() + "/config.yml");
FileWriter writer = new FileWriter(kafkactlConfig.getConfigPath());
yamlMapper.dump(rootNodeConfig, writer);

loginService.deleteJWTFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public class LoginService {
public LoginService(KafkactlConfig kafkactlConfig, ClusterResourceClient clusterResourceClient) {
this.kafkactlConfig = kafkactlConfig;
this.clusterResourceClient = clusterResourceClient;
this.jwtFile = new File(kafkactlConfig.getConfigPath() + "/jwt");
this.jwtFile = new File(kafkactlConfig.getConfigDirectory() + "/jwt");
// Create base kafkactl dir if not exists
File kafkactlDir = new File(kafkactlConfig.getConfigPath());
File kafkactlDir = new File(kafkactlConfig.getConfigDirectory());
if (!kafkactlDir.exists()) {
kafkactlDir.mkdir();
}
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/michelin/kafkactl/services/SystemService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.michelin.kafkactl.services;

public class SystemService {
private SystemService() { }

/**
* Get a system environment variable by name
* @param name The var name
* @return The system environment variable
*/
public static String getEnv(String name) {
return System.getenv(name);
}

/**
* Get a system property by name
* @param name The property name
* @return The system property name
*/
public static String getProperty(String name) {
return System.getProperty(name);
}

/**
* Set a system property
* @param key The name
* @param value The value
*/
public static void setProperty(String key, String value) {
System.setProperty(key, value);
}
}
1 change: 0 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ logger:

kafkactl:
version: @version@
config-path: ${user.home}/.kafkactl
table-format:
ResourceDefinition:
- "KIND:/metadata/name"
Expand Down
9 changes: 9 additions & 0 deletions src/test/java/com/michelin/kafkactl/KafkactlCommandTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.michelin.kafkactl;

import com.michelin.kafkactl.services.SystemService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import picocli.CommandLine;

import java.util.Collections;
import java.util.Map;

import static com.michelin.kafkactl.KafkactlConfig.KAFKACTL_CONFIG;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
class KafkactlCommandTest {
Expand Down
107 changes: 107 additions & 0 deletions src/test/java/com/michelin/kafkactl/KafkactlConfigTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.michelin.kafkactl;

import com.michelin.kafkactl.services.SystemService;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import static com.michelin.kafkactl.KafkactlConfig.KAFKACTL_CONFIG;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

class KafkactlConfigTest {
private final KafkactlConfig kafkactlConfig = new KafkactlConfig();

@Test
void shouldGetConfigDirectoryFromUserHome() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("");
mocked.when(() -> SystemService.getProperty(any()))
.thenAnswer(answer -> System.getProperty(answer.getArgument(0)));

String actual = kafkactlConfig.getConfigDirectory();
assertEquals(System.getProperty("user.home") + "/.kafkactl", actual);
}
}

@Test
void shouldGetConfigDirectoryFromKafkactlConfig() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("src/main/resources/config.yml");

String actual = kafkactlConfig.getConfigDirectory();
assertEquals("src" + System.getProperty("file.separator") + "main" + System.getProperty("file.separator") + "resources",
actual);
}
}

@Test
void shouldGetConfigDirectoryFromKafkactlConfigNoParent() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("config.yml");

String actual = kafkactlConfig.getConfigDirectory();
assertEquals(".", actual);
}
}

@Test
void shouldGetConfigDirectoryFromKafkactlConfigParentIsCurrent() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("./config.yml");

String actual = kafkactlConfig.getConfigDirectory();
assertEquals(".", actual);
}
}

@Test
void shouldGetConfigPathFromUserHome() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("");
mocked.when(() -> SystemService.getProperty(any()))
.thenAnswer(answer -> System.getProperty(answer.getArgument(0)));

String actual = kafkactlConfig.getConfigPath();
assertEquals(System.getProperty("user.home") + "/.kafkactl/config.yml", actual);
}
}

@Test
void shouldGetConfigPathFromKafkactlConfig() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("src/main/resources/config.yml");

String actual = kafkactlConfig.getConfigPath();
assertEquals("src/main/resources/config.yml", actual);
}
}

@Test
void shouldGetConfigPathFromKafkactlConfigNoParent() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("config.yml");

String actual = kafkactlConfig.getConfigPath();
assertEquals("config.yml", actual);
}
}

@Test
void shouldGetConfigPathFromKafkactlConfigParentIsCurrent() {
try (MockedStatic<SystemService> mocked = mockStatic(SystemService.class)) {
mocked.when(() -> SystemService.getEnv(KAFKACTL_CONFIG))
.thenReturn("./config.yml");

String actual = kafkactlConfig.getConfigPath();
assertEquals("./config.yml", actual);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,19 @@ void shouldUpdateConfigurationContext() throws IOException {
cmd.setOut(new PrintWriter(sw));

when(kafkactlConfig.getConfigPath())
.thenReturn("src/test/resources");
.thenReturn("src/test/resources/config.yml");

String backUp = Files.readString(Paths.get(kafkactlConfig.getConfigPath() + "/config.yml"));
String backUp = Files.readString(Paths.get(kafkactlConfig.getConfigPath()));

configService.updateConfigurationContext(contextToSet);

String actual = Files.readString(Paths.get(kafkactlConfig.getConfigPath() + "/config.yml"));
String actual = Files.readString(Paths.get(kafkactlConfig.getConfigPath()));

assertTrue(actual.contains(" current-namespace: namespace"));
assertTrue(actual.contains(" api: https://ns4kafka.com"));
assertTrue(actual.contains(" user-token: userToken"));

BufferedWriter writer = new BufferedWriter(new FileWriter(kafkactlConfig.getConfigPath() + "/config.yml", false));
BufferedWriter writer = new BufferedWriter(new FileWriter(kafkactlConfig.getConfigPath(), false));
writer.append(backUp);
writer.close();
}
Expand Down
Loading

0 comments on commit 77eb403

Please sign in to comment.