Okteto for Cloud Development in Java
/** * 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:

  1. Complete Cloud Development environment setup
  2. Remote Development Sessions with hot-reload
  3. File Synchronization between local and cloud
  4. Port Forwarding for local access to remote services
  5. Remote Debugging integration for Java applications
  6. Multi-service Development with dependencies
  7. Kubernetes-native Development without local clusters
  8. Spring Boot Integration for Java microservices
  9. Automated Build and Deployment pipelines
  10. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper