001/* 002 * Copyright 2025 devteam@scivics-lab.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, 011 * software distributed under the License is distributed on an 012 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the 014 * specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package com.scivicslab.actoriac.example; 019 020import com.scivicslab.actoriac.NodeGroup; 021import com.scivicslab.actoriac.Node; 022import com.scivicslab.pojoactor.core.ActorRef; 023import com.scivicslab.pojoactor.workflow.IIActorSystem; 024 025import java.io.InputStream; 026import java.util.List; 027import java.util.concurrent.CompletableFuture; 028 029/** 030 * Example demonstrating basic NodeGroup and Node usage. 031 * 032 * <p>This example shows how to: 033 * <ul> 034 * <li>Load an Ansible inventory file</li> 035 * <li>Create node actors for a group</li> 036 * <li>Execute commands on all nodes concurrently using the actor model</li> 037 * </ul> 038 * 039 * @author devteam@scivics-lab.com 040 */ 041public class ClusterExample { 042 043 public static void main(String[] args) { 044 System.out.println("=== actor-IaC Cluster Example ===\n"); 045 046 try { 047 // Load inventory file 048 InputStream inventoryStream = ClusterExample.class 049 .getResourceAsStream("/example-inventory.ini"); 050 051 if (inventoryStream == null) { 052 System.err.println("ERROR: example-inventory.ini not found in resources"); 053 System.err.println("Please create an inventory file to run this example"); 054 return; 055 } 056 057 // Create node group using Builder pattern (POJO, no ActorSystem dependency) 058 NodeGroup nodeGroup = new NodeGroup.Builder() 059 .withInventory(inventoryStream) 060 .build(); 061 System.out.println("Created node group and loaded inventory"); 062 System.out.println("Available groups: " + 063 nodeGroup.getInventory().getAllGroups().keySet()); 064 065 // Create actor system (using IIActorSystem for workflow support) 066 IIActorSystem actorSystem = new IIActorSystem("iac-system"); 067 068 // Create Node objects for webservers group 069 // Note: Nodes are pure POJOs with SSH functionality 070 List<Node> nodes = nodeGroup.createNodesForGroup("webservers"); 071 System.out.println("\nCreated " + nodes.size() + 072 " Node objects for webservers group"); 073 074 // Convert Node objects to actors 075 List<ActorRef<Node>> webservers = nodes.stream() 076 .map(node -> actorSystem.actorOf("node-" + node.getHostname().replace(".", "-"), node)) 077 .toList(); 078 System.out.println("Converted to " + webservers.size() + " node actors"); 079 080 // Example: Execute 'hostname' command on all webservers concurrently 081 System.out.println("\nExecuting 'echo hello' on all webservers..."); 082 083 List<CompletableFuture<Node.CommandResult>> futures = webservers.stream() 084 .map(nodeActor -> nodeActor.ask(node -> { 085 try { 086 return node.executeCommand("echo 'Hello from ' && hostname"); 087 } catch (Exception e) { 088 return new Node.CommandResult("", e.getMessage(), -1); 089 } 090 })) 091 .toList(); 092 093 // Wait for all commands to complete 094 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); 095 096 // Display results 097 System.out.println("\nResults:"); 098 for (int i = 0; i < futures.size(); i++) { 099 Node.CommandResult result = futures.get(i).get(); 100 System.out.println("Node " + (i + 1) + ":"); 101 System.out.println(" Exit Code: " + result.getExitCode()); 102 System.out.println(" Output: " + result.getStdout()); 103 if (!result.getStderr().isEmpty()) { 104 System.out.println(" Error: " + result.getStderr()); 105 } 106 } 107 108 System.out.println("\nNodeGroup info: " + nodeGroup); 109 110 // Clean up 111 actorSystem.terminate(); 112 System.out.println("\nActor system terminated"); 113 114 } catch (Exception e) { 115 System.err.println("Error: " + e.getMessage()); 116 e.printStackTrace(); 117 } 118 } 119}