/** * 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.