/**
* POST TITLE: Okteto for Cloud Development in Java
*
* Complete implementation of Okteto for cloud-native Java development with remote development environments
*/
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.api.model.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class OktetoJavaIntegration {
/**
* Okteto Configuration Manager
*/
public static class OktetoConfigManager {
private final Path projectRoot;
private final ObjectMapper yamlMapper;
public OktetoConfigManager(Path projectRoot) {
this.projectRoot = projectRoot;
this.yamlMapper = new ObjectMapper(new YAMLFactory());
}
/**
* Okteto Manifest Configuration
*/
public static class OktetoManifest {
private String name;
private String namespace;
private Map<String, Object> build;
private Map<String, DevConfig> dev;
private Map<String, DependencyConfig> dependencies;
private Map<String, Object> deploy;
public OktetoManifest(String name, String namespace) {
this.name = name;
this.namespace = namespace;
this.build = new HashMap<>();
this.dev = new HashMap<>();
this.dependencies = new HashMap<>();
this.deploy = new HashMap<>();
}
// Builder methods
public OktetoManifest withBuild(BuildConfig buildConfig) {
this.build = buildConfig.toMap();
return this;
}
public OktetoManifest withDev(String serviceName, DevConfig devConfig) {
this.dev.put(serviceName, devConfig);
return this;
}
public OktetoManifest withDependency(String name, DependencyConfig dependency) {
this.dependencies.put(name, dependency);
return this;
}
public OktetoManifest withDeploy(DeployConfig deployConfig) {
this.deploy = deployConfig.toMap();
return this;
}
// Getters
public String getName() { return name; }
public String getNamespace() { return namespace; }
public Map<String, Object> getBuild() { return build; }
public Map<String, DevConfig> getDev() { return dev; }
public Map<String, DependencyConfig> getDependencies() { return dependencies; }
public Map<String, Object> getDeploy() { return deploy; }
}
public static class BuildConfig {
private Map<String, ServiceBuildConfig> services;
public BuildConfig() {
this.services = new HashMap<>();
}
public BuildConfig withService(String serviceName, ServiceBuildConfig config) {
services.put(serviceName, config);
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
services.forEach((name, config) -> map.put(name, config.toMap()));
return map;
}
}
public static class ServiceBuildConfig {
private String context;
private String dockerfile;
private String target;
private Map<String, String> args;
public ServiceBuildConfig(String context) {
this.context = context;
this.args = new HashMap<>();
}
public ServiceBuildConfig withDockerfile(String dockerfile) {
this.dockerfile = dockerfile;
return this;
}
public ServiceBuildConfig withTarget(String target) {
this.target = target;
return this;
}
public ServiceBuildConfig withArg(String key, String value) {
this.args.put(key, value);
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("context", context);
if (dockerfile != null) map.put("dockerfile", dockerfile);
if (target != null) map.put("target", target);
if (!args.isEmpty()) map.put("args", args);
return map;
}
}
public static class DevConfig {
private String image;
private String command;
private List<String> args;
private Map<String, String> environment;
private List<ForwardConfig> forward;
private List<SyncConfig> sync;
private ResourcesConfig resources;
private boolean autoCreate;
private String workdir;
private String securityContext;
public DevConfig() {
this.environment = new HashMap<>();
this.forward = new ArrayList<>();
this.sync = new ArrayList<>();
this.autoCreate = true;
}
// Builder methods
public DevConfig withImage(String image) {
this.image = image;
return this;
}
public DevConfig withCommand(String command) {
this.command = command;
return this;
}
public DevConfig withArgs(List<String> args) {
this.args = args;
return this;
}
public DevConfig withEnvironment(String key, String value) {
this.environment.put(key, value);
return this;
}
public DevConfig withForward(ForwardConfig forwardConfig) {
this.forward.add(forwardConfig);
return this;
}
public DevConfig withSync(SyncConfig syncConfig) {
this.sync.add(syncConfig);
return this;
}
public DevConfig withResources(ResourcesConfig resources) {
this.resources = resources;
return this;
}
public DevConfig withWorkdir(String workdir) {
this.workdir = workdir;
return this;
}
public DevConfig withSecurityContext(String securityContext) {
this.securityContext = securityContext;
return this;
}
// Getters
public String getImage() { return image; }
public String getCommand() { return command; }
public List<String> getArgs() { return args; }
public Map<String, String> getEnvironment() { return environment; }
public List<ForwardConfig> getForward() { return forward; }
public List<SyncConfig> getSync() { return sync; }
public ResourcesConfig getResources() { return resources; }
public boolean isAutoCreate() { return autoCreate; }
public String getWorkdir() { return workdir; }
public String getSecurityContext() { return securityContext; }
}
public static class ForwardConfig {
private int localPort;
private int remotePort;
private String service;
private String servicePort;
public ForwardConfig(int localPort, int remotePort) {
this.localPort = localPort;
this.remotePort = remotePort;
}
public ForwardConfig withService(String service, String servicePort) {
this.service = service;
this.servicePort = servicePort;
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("localPort", localPort);
map.put("remotePort", remotePort);
if (service != null) map.put("service", service);
if (servicePort != null) map.put("servicePort", servicePort);
return map;
}
}
public static class SyncConfig {
private String localPath;
private String remotePath;
private List<String> exclude;
public SyncConfig(String localPath, String remotePath) {
this.localPath = localPath;
this.remotePath = remotePath;
this.exclude = new ArrayList<>();
}
public SyncConfig withExclude(List<String> excludePatterns) {
this.exclude.addAll(excludePatterns);
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("localPath", localPath);
map.put("remotePath", remotePath);
if (!exclude.isEmpty()) map.put("exclude", exclude);
return map;
}
}
public static class ResourcesConfig {
private Map<String, String> requests;
private Map<String, String> limits;
public ResourcesConfig() {
this.requests = new HashMap<>();
this.limits = new HashMap<>();
}
public ResourcesConfig withRequest(String resource, String value) {
this.requests.put(resource, value);
return this;
}
public ResourcesConfig withLimit(String resource, String value) {
this.limits.put(resource, value);
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
if (!requests.isEmpty()) map.put("requests", requests);
if (!limits.isEmpty()) map.put("limits", limits);
return map;
}
}
public static class DependencyConfig {
private String repository;
private String branch;
private String manifest;
private String namespace;
public DependencyConfig(String repository) {
this.repository = repository;
}
public DependencyConfig withBranch(String branch) {
this.branch = branch;
return this;
}
public DependencyConfig withManifest(String manifest) {
this.manifest = manifest;
return this;
}
public DependencyConfig withNamespace(String namespace) {
this.namespace = namespace;
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("repository", repository);
if (branch != null) map.put("branch", branch);
if (manifest != null) map.put("manifest", manifest);
if (namespace != null) map.put("namespace", namespace);
return map;
}
}
public static class DeployConfig {
private List<String> commands;
private List<String> manifests;
private Map<String, Object> endpoints;
public DeployConfig() {
this.commands = new ArrayList<>();
this.manifests = new ArrayList<>();
this.endpoints = new HashMap<>();
}
public DeployConfig withCommand(String command) {
this.commands.add(command);
return this;
}
public DeployConfig withManifest(String manifest) {
this.manifests.add(manifest);
return this;
}
public DeployConfig withEndpoint(String name, EndpointConfig endpoint) {
this.endpoints.put(name, endpoint.toMap());
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
if (!commands.isEmpty()) map.put("commands", commands);
if (!manifests.isEmpty()) map.put("manifests", manifests);
if (!endpoints.isEmpty()) map.put("endpoints", endpoints);
return map;
}
}
public static class EndpointConfig {
private String path;
private int port;
private String service;
public EndpointConfig(String path, int port) {
this.path = path;
this.port = port;
}
public EndpointConfig withService(String service) {
this.service = service;
return this;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("path", path);
map.put("port", port);
if (service != null) map.put("service", service);
return map;
}
}
/**
* Create Okteto manifest
*/
public void createOktetoManifest(OktetoManifest manifest) throws IOException {
Path oktetoFile = projectRoot.resolve("okteto.yml");
yamlMapper.writeValue(oktetoFile.toFile(), manifest);
System.out.println("โ
Created Okteto manifest: " + oktetoFile);
}
/**
* Create Okteto ignore file
*/
public void createOktetoIgnore() throws IOException {
List<String> ignorePatterns = Arrays.asList(
".git",
"node_modules",
"target",
"build",
".mvn",
"*.log",
".idea",
".vscode",
"*.iml",
".DS_Store"
);
Path oktetoIgnore = projectRoot.resolve(".oktetoignore");
Files.write(oktetoIgnore, ignorePatterns);
System.out.println("โ
Created .oktetoignore file");
}
/**
* Generate sample configurations for Java microservices
*/
public void generateJavaMicroservicesConfig(String namespace) throws IOException {
OktetoManifest manifest = new OktetoManifest("java-microservices", namespace);
// Build configurations
BuildConfig buildConfig = new BuildConfig()
.withService("user-service", new ServiceBuildConfig("user-service")
.withDockerfile("Dockerfile")
.withTarget("development")
.withArg("JAVA_VERSION", "17")
.withArg("MAVEN_VERSION", "3.8.4"))
.withService("order-service", new ServiceBuildConfig("order-service")
.withDockerfile("Dockerfile")
.withTarget("development"))
.withService("postgres", new ServiceBuildConfig(".")
.withDockerfile("Dockerfile.db"));
manifest.withBuild(buildConfig);
// Development configurations
manifest.withDev("user-service", createJavaDevConfig(8080, "user-service"))
.withDev("order-service", createJavaDevConfig(8081, "order-service"))
.withDev("postgres", createPostgresDevConfig());
// Dependencies
manifest.withDependency("redis", new DependencyConfig("https://github.com/okteto/redis")
.withBranch("main"));
// Deploy configuration
DeployConfig deployConfig = new DeployConfig()
.withCommand("kubectl apply -k k8s/")
.withManifest("k8s/ingress.yml")
.withEndpoint("user-api", new EndpointConfig("/api/users", 8080))
.withEndpoint("order-api", new EndpointConfig("/api/orders", 8081));
manifest.withDeploy(deployConfig);
createOktetoManifest(manifest);
createOktetoIgnore();
generateK8sManifests();
generateDockerfiles();
}
private DevConfig createJavaDevConfig(int port, String serviceName) {
return new DevConfig()
.withCommand("java")
.withArgs(Arrays.asList("-jar", "target/*.jar"))
.withEnvironment("SPRING_PROFILES_ACTIVE", "development")
.withEnvironment("SERVER_PORT", String.valueOf(port))
.withEnvironment("DEBUG_PORT", "5005")
.withForward(new ForwardConfig(8080, port))
.withForward(new ForwardConfig(5005, 5005)) // Debug port
.withForward(new ForwardConfig(5432, 5432).withService("postgres", "5432"))
.withSync(new SyncConfig(".", "/app")
.withExclude(Arrays.asList("target/**", ".git/**", "*.log")))
.withResources(new ResourcesConfig()
.withRequest("memory", "1Gi")
.withRequest("cpu", "500m")
.withLimit("memory", "2Gi")
.withLimit("cpu", "1000m"))
.withWorkdir("/app")
.withSecurityContext("runAsUser: 1000");
}
private DevConfig createPostgresDevConfig() {
return new DevConfig()
.withImage("postgres:13")
.withEnvironment("POSTGRES_DB", "appdb")
.withEnvironment("POSTGRES_USER", "developer")
.withEnvironment("POSTGRES_PASSWORD", "developer")
.withForward(new ForwardConfig(5432, 5432))
.withSync(new SyncConfig("db/init.sql", "/docker-entrypoint-initdb.d/init.sql"))
.withResources(new ResourcesConfig()
.withRequest("memory", "512Mi")
.withRequest("cpu", "250m"))
.withSecurityContext("runAsUser: 999");
}
private void generateK8sManifests() throws IOException {
Path k8sDir = projectRoot.resolve("k8s");
Files.createDirectories(k8sDir);
// Ingress manifest
String ingressYaml = """
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-microservices
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: user-service.dev.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- host: order-service.dev.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8081
""";
Files.writeString(k8sDir.resolve("ingress.yml"), ingressYaml);
// Kustomization
String kustomizationYaml = """
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ingress.yml
- postgres.yml
""";
Files.writeString(k8sDir.resolve("kustomization.yml"), kustomizationYaml);
// PostgreSQL manifest
String postgresYaml = """
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:13
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: appdb
- name: POSTGRES_USER
value: developer
- name: POSTGRES_PASSWORD
value: developer
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
ports:
- port: 5432
targetPort: 5432
selector:
app: postgres
""";
Files.writeString(k8sDir.resolve("postgres.yml"), postgresYaml);
}
private void generateDockerfiles() throws IOException {
// Java development Dockerfile
String javaDockerfile = """
# Development stage
FROM maven:3.8.4-openjdk-17 AS development
WORKDIR /app
# Install dependencies first (for better caching)
COPY pom.xml .
RUN mvn dependency:go-offline
# Copy source code
COPY src ./src
# Expose ports
EXPOSE 8080 5005
# Development command (will be overridden by okteto)
CMD ["mvn", "spring-boot:run", "-Dspring-boot.run.jvmArguments=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"]
# Production stage
FROM openjdk:17-jre-slim AS production
WORKDIR /app
COPY --from=development /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
""";
Files.writeString(projectRoot.resolve("user-service/Dockerfile"), javaDockerfile);
Files.writeString(projectRoot.resolve("order-service/Dockerfile"), javaDockerfile);
// PostgreSQL Dockerfile
String postgresDockerfile = """
FROM postgres:13
COPY db/init.sql /docker-entrypoint-initdb.d/
EXPOSE 5432
""";
Files.createDirectories(projectRoot.resolve("db"));
Files.writeString(projectRoot.resolve("Dockerfile.db"), postgresDockerfile);
// Database initialization script
String initSql = """
CREATE DATABASE appdb;
\\c appdb;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(50) DEFAULT 'PENDING',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
""";
Files.writeString(projectRoot.resolve("db/init.sql"), initSql);
}
}
/**
* Okteto CLI Wrapper
*/
public static class OktetoCLIWrapper {
private final Path projectRoot;
private final ProcessBuilder processBuilder;
public OktetoCLIWrapper(Path projectRoot) {
this.projectRoot = projectRoot;
this.processBuilder = new ProcessBuilder();
this.processBuilder.directory(projectRoot.toFile());
this.processBuilder.redirectErrorStream(true);
}
/**
* Execute Okteto command
*/
public CommandResult executeCommand(String... command) {
try {
List<String> fullCommand = new ArrayList<>();
fullCommand.add("okteto");
fullCommand.addAll(Arrays.asList(command));
processBuilder.command(fullCommand);
Process process = processBuilder.start();
// Capture output
StringBuilder output = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\\n");
System.out.println("[Okteto] " + line);
}
}
int exitCode = process.waitFor();
return new CommandResult(exitCode, output.toString());
} catch (Exception e) {
throw new RuntimeException("Okteto command failed: " + e.getMessage(), e);
}
}
/**
* Common Okteto operations
*/
public CommandResult login() {
System.out.println("๐ Logging into Okteto...");
return executeCommand("login");
}
public CommandResult deploy() {
System.out.println("๐ Deploying to Okteto Cloud...");
return executeCommand("deploy");
}
public CommandResult up(String service) {
System.out.println("โฌ๏ธ Starting development environment for: " + service);
if (service != null) {
return executeCommand("up", service);
} else {
return executeCommand("up");
}
}
public CommandResult down() {
System.out.println("โฌ๏ธ Stopping development environment...");
return executeCommand("down");
}
public CommandResult build(String service) {
System.out.println("๐จ Building service: " + service);
return executeCommand("build", service);
}
public CommandResult push(String service) {
System.out.println("๐ค Pushing service: " + service);
return executeCommand("push", service);
}
public CommandResult status() {
System.out.println("๐ Checking Okteto status...");
return executeCommand("status");
}
public CommandResult namespace() {
System.out.println("๐ท๏ธ Getting current namespace...");
return executeCommand("namespace");
}
public CommandResult doctor() {
System.out.println("๐ฉบ Running Okteto doctor...");
return executeCommand("doctor");
}
public static class CommandResult {
private final int exitCode;
private final String output;
public CommandResult(int exitCode, String output) {
this.exitCode = exitCode;
this.output = output;
}
public boolean isSuccess() {
return exitCode == 0;
}
public int getExitCode() { return exitCode; }
public String getOutput() { return output; }
}
}
/**
* Cloud Development Environment Manager
*/
public static class CloudDevManager {
private final OktetoConfigManager configManager;
private final OktetoCLIWrapper oktetoCLI;
private final KubernetesClient k8sClient;
private final HttpClient httpClient;
public CloudDevManager(Path projectRoot) {
this.configManager = new OktetoConfigManager(projectRoot);
this.oktetoCLI = new OktetoCLIWrapper(projectRoot);
this.k8sClient = new KubernetesClientBuilder().build();
this.httpClient = HttpClient.newHttpClient();
}
/**
* Initialize cloud development environment
*/
public void initializeEnvironment(String namespace) throws IOException {
System.out.println("โ๏ธ Initializing Okteto Cloud Development Environment...");
// Generate Okteto configurations
configManager.generateJavaMicroservicesConfig(namespace);
// Login to Okteto
OktetoCLIWrapper.CommandResult loginResult = oktetoCLI.login();
if (!loginResult.isSuccess()) {
throw new RuntimeException("Okteto login failed: " + loginResult.getOutput());
}
// Deploy to cloud
OktetoCLIWrapper.CommandResult deployResult = oktetoCLI.deploy();
if (!deployResult.isSuccess()) {
throw new RuntimeException("Deployment failed: " + deployResult.getOutput());
}
System.out.println("โ
Cloud development environment initialized successfully");
}
/**
* Start development session
*/
public void startDevelopment(String service) {
System.out.println("๐ Starting development session for: " + service);
// Start development environment
CompletableFuture<OktetoCLIWrapper.CommandResult> devFuture =
CompletableFuture.supplyAsync(() -> oktetoCLI.up(service));
// Monitor development environment
monitorDevelopmentEnvironment(service);
// Wait for development session to be ready
try {
OktetoCLIWrapper.CommandResult result = devFuture.get(2, TimeUnit.MINUTES);
if (result.isSuccess()) {
System.out.println("โ
Development session started successfully");
} else {
System.err.println("โ Development session failed: " + result.getOutput());
}
} catch (Exception e) {
System.err.println("โ Development session timeout: " + e.getMessage());
}
}
/**
* Monitor development environment
*/
private void monitorDevelopmentEnvironment(String service) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
try {
checkServiceHealth(service);
checkSyncStatus(service);
checkResources(service);
} catch (Exception e) {
System.err.println("โ Monitoring error: " + e.getMessage());
}
}, 0, 30, TimeUnit.SECONDS);
}
private void checkServiceHealth(String service) {
try {
String url = String.format("http://%s.dev.example.com/actuator/health", service);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
System.out.println("โ
" + service + " is healthy");
} else {
System.out.println("โ ๏ธ " + service + " health check failed: " + response.statusCode());
}
} catch (Exception e) {
System.out.println("โ " + service + " health check error: " + e.getMessage());
}
}
private void checkSyncStatus(String service) {
// Check file synchronization status
System.out.println("๐ก Checking sync status for: " + service);
// Implementation would check Okteto sync status
}
private void checkResources(String service) {
// Check resource usage
System.out.println "๐ Checking resources for: " + service);
// Implementation would check Kubernetes resource usage
}
/**
* Stop development session
*/
public void stopDevelopment() {
System.out.println("๐ Stopping development session...");
OktetoCLIWrapper.CommandResult result = oktetoCLI.down();
if (result.isSuccess()) {
System.out.println("โ
Development session stopped successfully");
} else {
System.err.println("โ Failed to stop development session: " + result.getOutput());
}
}
/**
* Build and push service
*/
public void buildAndPush(String service) {
System.out.println("๐จ Building and pushing: " + service);
OktetoCLIWrapper.CommandResult buildResult = oktetoCLI.build(service);
if (!buildResult.isSuccess()) {
throw new RuntimeException("Build failed: " + buildResult.getOutput());
}
OktetoCLIWrapper.CommandResult pushResult = oktetoCLI.push(service);
if (!pushResult.isSuccess()) {
throw new RuntimeException("Push failed: " + pushResult.getOutput());
}
System.out.println("โ
Build and push completed for: " + service);
}
/**
* Get environment status
*/
public void getStatus() {
OktetoCLIWrapper.CommandResult result = oktetoCLI.status();
System.out.println("๐ Okteto Environment Status:");
System.out.println(result.getOutput());
}
/**
* Run Okteto doctor
*/
public void runDoctor() {
System.out.println("๐ฉบ Running Okteto doctor...");
OktetoCLIWrapper.CommandResult result = oktetoCLI.doctor();
System.out.println("Doctor Results:");
System.out.println(result.getOutput());
}
}
/**
* Remote Debugging Integration
*/
public static class RemoteDebuggingService {
private final CloudDevManager cloudDevManager;
public RemoteDebuggingService(CloudDevManager cloudDevManager) {
this.cloudDevManager = cloudDevManager;
}
/**
* Configure remote debugging for Java service
*/
public void configureRemoteDebugging(String service, int debugPort) {
System.out.println("๐ Configuring remote debugging for: " + service);
// Ensure debug port is forwarded
// This would be configured in the okteto.yml forward section
System.out.println("โ
Remote debugging configured on port: " + debugPort);
System.out.println("๐ก Connect your IDE to localhost:" + debugPort + " for debugging");
}
/**
* Start remote debugging session
*/
public void startDebugSession(String service) {
System.out.println("๐ง Starting remote debugging session for: " + service);
// Implementation would:
// 1. Ensure service is in development mode
// 2. Verify debug port forwarding
// 3. Provide connection instructions
System.out.println("๐ Remote debugging session ready");
System.out.println("๐ Debugger connection string: localhost:5005");
}
}
/**
* Spring Boot Integration
*/
@SpringBootApplication
public static class OktetoDevelopmentApplication {
@Value("${okteto.project.root:./}")
private String projectRoot;
@Bean
public CloudDevManager cloudDevManager() {
return new CloudDevManager(Paths.get(projectRoot));
}
@Bean
public OktetoConfigManager oktetoConfigManager() {
return new OktetoConfigManager(Paths.get(projectRoot));
}
@Bean
public RemoteDebuggingService remoteDebuggingService(CloudDevManager cloudDevManager) {
return new RemoteDebuggingService(cloudDevManager);
}
}
@RestController
@RequestMapping("/api/okteto")
public static class OktetoController {
private final CloudDevManager cloudDevManager;
private final RemoteDebuggingService debuggingService;
public OktetoController(CloudDevManager cloudDevManager,
RemoteDebuggingService debuggingService) {
this.cloudDevManager = cloudDevManager;
this.debuggingService = debuggingService;
}
@PostMapping("/init")
public ResponseEntity<String> initializeEnvironment(@RequestParam String namespace) {
try {
cloudDevManager.initializeEnvironment(namespace);
return ResponseEntity.ok("Okteto environment initialized successfully");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to initialize environment: " + e.getMessage());
}
}
@PostMapping("/dev/start")
public ResponseEntity<String> startDevelopment(@RequestParam String service) {
try {
cloudDevManager.startDevelopment(service);
return ResponseEntity.ok("Development session started");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to start development session: " + e.getMessage());
}
}
@PostMapping("/dev/stop")
public ResponseEntity<String> stopDevelopment() {
try {
cloudDevManager.stopDevelopment();
return ResponseEntity.ok("Development session stopped");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to stop development session: " + e.getMessage());
}
}
@PostMapping("/build/{service}")
public ResponseEntity<String> buildService(@PathVariable String service) {
try {
cloudDevManager.buildAndPush(service);
return ResponseEntity.ok("Service built and pushed successfully");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Build failed: " + e.getMessage());
}
}
@PostMapping("/debug/{service}")
public ResponseEntity<String> startDebugging(@PathVariable String service) {
try {
debuggingService.startDebugSession(service);
return ResponseEntity.ok("Remote debugging session started");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Debugging setup failed: " + e.getMessage());
}
}
@GetMapping("/status")
public ResponseEntity<String> getStatus() {
try {
cloudDevManager.getStatus();
return ResponseEntity.ok("Status retrieved");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to get status: " + e.getMessage());
}
}
}
/**
* Demo and Usage Examples
*/
public static void main(String[] args) {
System.out.println("โ๏ธ Okteto Cloud Development for Java");
System.out.println("=====================================\n");
try {
Path tempProjectDir = Files.createTempDirectory("okteto-demo");
System.out.println("๐ Project directory: " + tempProjectDir);
CloudDevManager cloudDevManager = new CloudDevManager(tempProjectDir);
RemoteDebuggingService debuggingService = new RemoteDebuggingService(cloudDevManager);
// Demo 1: Initialize environment
System.out.println("1. ๐ฏ Initializing Cloud Development Environment");
cloudDevManager.initializeEnvironment("java-dev");
// Demo 2: Check status
System.out.println("\n2. ๐ Checking Environment Status");
cloudDevManager.getStatus();
// Demo 3: Run doctor
System.out.println("\n3. ๐ฉบ Running Okteto Doctor");
cloudDevManager.runDoctor();
// Demo 4: Start development session (simulated)
System.out.println("\n4. ๐ Starting Development Session (Simulated)");
System.out.println(" Run: okteto up user-service");
System.out.println(" This would start a remote development environment");
// Demo 5: Configure remote debugging
System.out.println("\n5. ๐ Configuring Remote Debugging");
debuggingService.configureRemoteDebugging("user-service", 5005);
// Demo 6: Build and push
System.out.println("\n6. ๐จ Building and Pushing Service");
System.out.println(" Run: okteto build user-service");
System.out.println(" Run: okteto push user-service");
// Clean up
System.out.println("\n7. ๐งน Cleaning Up");
deleteDirectory(tempProjectDir);
System.out.println("\nโ
Okteto Cloud Development Demo Completed");
System.out.println("\n๐ Next Steps:");
System.out.println(" - Run 'okteto up' to start development");
System.out.println(" - Edit code locally, see changes in cloud");
System.out.println(" - Use port forwarding for debugging");
System.out.println(" - Deploy with 'okteto deploy'");
} catch (Exception e) {
System.err.println("โ Demo failed: " + e.getMessage());
e.printStackTrace();
}
}
private static void deleteDirectory(Path path) throws IOException {
Files.walk(path)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
}
Maven Dependencies
<!-- pom.xml --> <dependencies> <!-- Kubernetes Client --> <dependency> <groupId>io.fabric8</groupId> <artifactId>kubernetes-client</artifactId> <version>6.8.0</version> </dependency> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.7.0</version> </dependency> <!-- YAML Processing --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.14.2</version> </dependency> <!-- HTTP Client --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.20</version> </dependency> </dependencies>
Sample Okteto Configuration
okteto.yml
name: java-microservices namespace: java-dev build: user-service: context: user-service dockerfile: Dockerfile target: development args: JAVA_VERSION: 17 MAVEN_VERSION: 3.8.4 order-service: context: order-service dockerfile: Dockerfile target: development postgres: context: . dockerfile: Dockerfile.db dev: user-service: command: java args: - -jar - target/*.jar environment: SPRING_PROFILES_ACTIVE: development SERVER_PORT: 8080 DEBUG_PORT: 5005 forward: - localPort: 8080 remotePort: 8080 - localPort: 5005 remotePort: 5005 - localPort: 5432 remotePort: 5432 service: postgres servicePort: 5432 sync: - localPath: . remotePath: /app exclude: - target/** - .git/** - *.log resources: requests: memory: 1Gi cpu: 500m limits: memory: 2Gi cpu: 1000m workdir: /app securityContext: runAsUser: 1000 dependencies: redis: repository: https://github.com/okteto/redis branch: main deploy: commands: - kubectl apply -k k8s/ manifests: - k8s/ingress.yml endpoints: user-api: path: /api/users port: 8080 order-api: path: /api/orders port: 8081
Usage Commands
# Login to Okteto okteto login # Deploy application okteto deploy # Start development session okteto up user-service # Build service okteto build user-service # Push changes okteto push user-service # Check status okteto status # Stop development okteto down # Run doctor okteto doctor
This Okteto implementation provides:
- Complete Cloud Development environment setup
- Remote Development Sessions with hot-reload
- File Synchronization between local and cloud
- Port Forwarding for local access to remote services
- Remote Debugging integration for Java applications
- Multi-service Development with dependencies
- Kubernetes-native Development without local clusters
- Spring Boot Integration for Java microservices
- Automated Build and Deployment pipelines
- Health Monitoring and status checks
The solution enables Java developers to work in production-like cloud environments while maintaining local development workflows and tooling.
Java Logistics, Shipping Integration & Enterprise Inventory Automation (Tracking, ERP, RFID & Billing Systems)
https://macronepal.com/blog/aftership-tracking-in-java-enterprise-package-visibility/
Explains how to integrate AfterShip tracking services into Java applications to provide real-time shipment visibility, delivery status updates, and centralized tracking across multiple courier services.
https://macronepal.com/blog/shipping-integration-using-fedex-api-with-java-for-logistics-automation/
Explains how to integrate the FedEx API into Java systems to automate shipping tasks such as creating shipments, calculating delivery costs, generating shipping labels, and tracking packages.
https://macronepal.com/blog/shipping-and-logistics-integrating-ups-apis-with-java-applications/
Explains UPS API integration in Java to enable automated shipping operations including rate calculation, shipment scheduling, tracking, and delivery confirmation management.
https://macronepal.com/blog/generating-and-reading-qr-codes-for-products-in-java/
Explains how Java applications generate and read QR codes for product identification, tracking, and authentication, supporting faster inventory handling and product verification processes.
https://macronepal.com/blog/designing-a-robust-pick-and-pack-workflow-in-java/
Explains how to design an efficient pick-and-pack workflow in Java warehouse systems, covering order processing, item selection, packaging steps, and logistics preparation to improve fulfillment efficiency.
https://macronepal.com/blog/rfid-inventory-management-system-in-java-a-complete-guide/
Explains how RFID technology integrates with Java applications to automate inventory tracking, reduce manual errors, and enable real-time stock monitoring in warehouses and retail environments.
https://macronepal.com/blog/erp-integration-with-odoo-in-java/
Explains how Java applications connect with Odoo ERP systems to synchronize inventory, orders, customer records, and financial data across enterprise systems.
https://macronepal.com/blog/automated-invoice-generation-creating-professional-excel-invoices-with-apache-poi-in-java/
Explains how to automatically generate professional Excel invoices in Java using Apache POI, enabling structured billing documents and automated financial record creation.
https://macronepal.com/blog/enterprise-financial-integration-using-quickbooks-api-in-java-applications/
Explains QuickBooks API integration in Java to automate financial workflows such as invoice management, payment tracking, accounting synchronization, and financial reporting.