feat: HTTP Tool 생성 시 dat-was-lib의 application-glow-local.yml 탐색 및 append 로직 적용
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 28s

This commit is contained in:
jade
2026-09-08 14:11:29 +09:00
parent 9a8f716ec7
commit d45720d3e4

View File

@@ -8,6 +8,7 @@ import java.nio.file.Paths;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -139,8 +140,9 @@ public class ToolScaffolder {
for (ToolMethodDefinition tool : tools) { for (ToolMethodDefinition tool : tools) {
writeGroupedToolFiles(moduleRoot, sourceRoot, dtoDir, definitionDir, bizPackage, tool, moduleName, log); writeGroupedToolFiles(moduleRoot, sourceRoot, dtoDir, definitionDir, bizPackage, tool, moduleName, log);
if ("HTTP".equalsIgnoreCase(tool.routingType())) { if ("HTTP".equalsIgnoreCase(tool.routingType())) {
ensureLocalHttpApiConfiguration(moduleRoot, tool.httpApiName(), Path glowConfig = ensureLocalHttpApiConfiguration(moduleRoot, tool.httpApiName(),
toToolName(moduleName, tool.group(), toPascalCase(tool.baseName()))); toToolName(moduleName, tool.group(), toPascalCase(tool.baseName())));
log.append("[HTTP Config] ").append(glowConfig).append("\n");
} }
} }
log.append("[Converter] ").append(converterFile).append("\n"); log.append("[Converter] ").append(converterFile).append("\n");
@@ -1546,7 +1548,8 @@ public class ToolScaffolder {
if (isHttp) { if (isHttp) {
Path moduleRoot = rootDir.resolve(moduleName).toAbsolutePath().normalize(); Path moduleRoot = rootDir.resolve(moduleName).toAbsolutePath().normalize();
Path projectRoot = moduleRoot.getParent(); Path projectRoot = moduleRoot.getParent();
ensureLocalHttpApiConfiguration(projectRoot, httpApiName, toolName); Path glowConfig = ensureLocalHttpApiConfiguration(projectRoot, httpApiName, toolName);
log.append("[HTTP Config] ").append(glowConfig).append("\n");
} }
Path generatedTestDir = rootDir.resolve(Paths.get(moduleName, "src/test/java/io/shinhanlife/dat/mcc/biz", group.toLowerCase(), "usecase")); Path generatedTestDir = rootDir.resolve(Paths.get(moduleName, "src/test/java/io/shinhanlife/dat/mcc/biz", group.toLowerCase(), "usecase"));
@@ -1757,13 +1760,76 @@ public class ToolScaffolder {
.toLowerCase(Locale.ROOT); .toLowerCase(Locale.ROOT);
} }
private static void ensureLocalHttpApiConfiguration(Path projectRoot, String httpApiName, String toolName) throws IOException { private static Path findGlowLocalConfigPath(Path startPath) {
Path localConfigPath = projectRoot.resolve("src/main/resources/glow/application-glow-local.yml"); String sourceDir = System.getProperty("AXHUB_SOURCE_DIR");
if (sourceDir == null) {
sourceDir = System.getenv("AXHUB_SOURCE_DIR");
}
List<Path> baseDirs = new ArrayList<>();
if (startPath != null) {
baseDirs.add(startPath);
if (startPath.getParent() != null) {
baseDirs.add(startPath.getParent());
}
}
if (sourceDir != null && !sourceDir.isBlank()) {
baseDirs.add(Paths.get(sourceDir.trim()));
}
baseDirs.add(Paths.get("."));
String[] subPaths = {
"dat-was-lib/src/main/resources/glow",
"src/main/resources/glow"
};
String[] fileNames = {
"application-glow-local.yml",
"application-glow-local.yaml",
"application-glow-local.xml"
};
// 1. 이미 존재하는 파일 우선 탐색 (dat-was-lib 우선)
for (Path base : baseDirs) {
for (String sub : subPaths) {
for (String name : fileNames) {
Path candidate = base.resolve(sub).resolve(name).normalize();
if (Files.exists(candidate)) {
return candidate;
}
}
}
}
// 2. dat-was-lib 디렉토리가 존재하는 디렉토리 찾기
for (Path base : baseDirs) {
Path libDir = base.resolve("dat-was-lib");
if (Files.isDirectory(libDir)) {
return libDir.resolve("src/main/resources/glow/application-glow-local.yml").normalize();
}
}
// 3. startPath 형제(sibling)로 dat-was-lib 찾기
if (startPath != null) {
Path libSibling = startPath.resolveSibling("dat-was-lib");
if (Files.isDirectory(libSibling)) {
return libSibling.resolve("src/main/resources/glow/application-glow-local.yml").normalize();
}
}
// 4. Fallback
if (sourceDir != null && !sourceDir.isBlank()) {
return Paths.get(sourceDir.trim()).resolve("dat-was-lib/src/main/resources/glow/application-glow-local.yml").normalize();
}
return Paths.get("dat-was-lib/src/main/resources/glow/application-glow-local.yml").normalize();
}
private static Path ensureLocalHttpApiConfiguration(Path projectRoot, String httpApiName, String toolName) throws IOException {
Path localConfigPath = findGlowLocalConfigPath(projectRoot);
Files.createDirectories(localConfigPath.getParent()); Files.createDirectories(localConfigPath.getParent());
String existing = Files.exists(localConfigPath) ? Files.readString(localConfigPath, StandardCharsets.UTF_8) : ""; String existing = Files.exists(localConfigPath) ? Files.readString(localConfigPath, StandardCharsets.UTF_8) : "";
if (java.util.regex.Pattern.compile("(?m)^\\s*-\\s+name:\\s*" if (java.util.regex.Pattern.compile("(?m)^\\s*-\\s+name:\\s*"
+ java.util.regex.Pattern.quote(httpApiName) + "\\s*$").matcher(existing).find()) { + java.util.regex.Pattern.quote(httpApiName) + "\\s*$").matcher(existing).find()) {
return; return localConfigPath;
} }
String environmentKey = toPackageSegment(httpApiName).toUpperCase(Locale.ROOT).replace('-', '_'); String environmentKey = toPackageSegment(httpApiName).toUpperCase(Locale.ROOT).replace('-', '_');
String apiEntry = """ String apiEntry = """
@@ -1774,6 +1840,9 @@ public class ToolScaffolder {
content-type: application/json;charset=UTF-8 content-type: application/json;charset=UTF-8
biz-pod: false biz-pod: false
""".formatted(httpApiName, environmentKey, environmentKey, toolName).stripTrailing() + "\n"; """.formatted(httpApiName, environmentKey, environmentKey, toolName).stripTrailing() + "\n";
boolean isCrlf = existing.contains("\r\n");
String formattedApiEntry = isCrlf ? apiEntry.replace("\n", "\r\n") : apiEntry;
if (existing.isBlank()) { if (existing.isBlank()) {
existing = """ existing = """
spring: spring:
@@ -1786,25 +1855,35 @@ public class ToolScaffolder {
http: http:
api-list: api-list:
""" + apiEntry; """ + apiEntry;
if (isCrlf) {
existing = existing.replace("\n", "\r\n");
}
} else if (existing.contains("\r\n mci:")) {
existing = existing.replace("\r\n mci:", "\r\n" + formattedApiEntry + " mci:");
} else if (existing.contains("\n mci:")) { } else if (existing.contains("\n mci:")) {
existing = existing.replace("\n mci:", "\n" + apiEntry + " mci:"); existing = existing.replace("\n mci:", "\n" + formattedApiEntry + " mci:");
} else if (existing.contains("\r\naxhub:")) {
existing = existing.replace("\r\naxhub:", "\r\n" + formattedApiEntry + "axhub:");
} else if (existing.contains("\naxhub:")) { } else if (existing.contains("\naxhub:")) {
existing = existing.replace("\naxhub:", apiEntry + "axhub:"); existing = existing.replace("\naxhub:", "\n" + formattedApiEntry + "axhub:");
} else if (existing.contains("api-list:")) { } else if (existing.contains("api-list:")) {
existing += apiEntry; existing += formattedApiEntry;
} else { } else {
throw new IllegalStateException("application-glow-local.yml must define glow.communication.http.api-list"); throw new IllegalStateException("application-glow-local.yml must define glow.communication.http.api-list");
} }
if (!existing.contains("axhub:\n mock:\n http:\n enabled: true")) { if (!existing.contains("axhub:\n mock:\n http:\n enabled: true")
existing += """ && !existing.contains("axhub:\r\n mock:\r\n http:\r\n enabled: true")) {
String mockConfig = """
axhub: axhub:
mock: mock:
http: http:
enabled: true enabled: true
"""; """;
existing += isCrlf ? mockConfig.replace("\n", "\r\n") : mockConfig;
} }
writeUtf8(localConfigPath, existing); writeUtf8(localConfigPath, existing);
return localConfigPath;
} }
private static void writeUtf8(Path path, String content) throws IOException { private static void writeUtf8(Path path, String content) throws IOException {