001/* 002 * Copyright 2025 devteam@scivicslab.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.log; 019 020import java.sql.Connection; 021import java.util.List; 022 023/** 024 * Interface for distributed log storage. 025 * 026 * <p>This interface defines operations for storing and querying logs 027 * from distributed workflow execution across multiple nodes.</p> 028 * 029 * <p>The interface provides singleton access for components that need 030 * database connection (e.g., WorkflowReporter). The singleton is set 031 * by RunCLI at workflow startup and cleared after execution.</p> 032 * 033 * @author devteam@scivicslab.com 034 */ 035public interface DistributedLogStore extends AutoCloseable { 036 037 // ======================================================================== 038 // Singleton management 039 // ======================================================================== 040 041 /** Singleton instance holder */ 042 class InstanceHolder { 043 private static DistributedLogStore instance; 044 } 045 046 /** 047 * Sets the singleton instance. 048 * 049 * <p>Called by RunCLI when starting workflow execution.</p> 050 * 051 * @param store the DistributedLogStore instance to use globally 052 */ 053 static void setInstance(DistributedLogStore store) { 054 InstanceHolder.instance = store; 055 } 056 057 /** 058 * Gets the singleton instance. 059 * 060 * @return the global DistributedLogStore instance, or null if not set 061 */ 062 static DistributedLogStore getInstance() { 063 return InstanceHolder.instance; 064 } 065 066 // ======================================================================== 067 // Connection access 068 // ======================================================================== 069 070 /** 071 * Gets the database connection for read-only operations. 072 * 073 * <p>Components should NOT close this connection. The connection is owned 074 * by RunCLI and will be closed when the workflow execution ends.</p> 075 * 076 * @return the JDBC connection 077 */ 078 Connection getConnection(); 079 080 /** 081 * Starts a new workflow execution session. 082 * 083 * @param workflowName name of the workflow being executed 084 * @param nodeCount number of nodes participating in this session 085 * @return session ID for subsequent log entries 086 */ 087 long startSession(String workflowName, int nodeCount); 088 089 /** 090 * Starts a new workflow execution session with overlay and inventory info. 091 * 092 * @param workflowName name of the workflow being executed 093 * @param overlayName name of the overlay being used (may be null) 094 * @param inventoryName name of the inventory file being used (may be null) 095 * @param nodeCount number of nodes participating in this session 096 * @return session ID for subsequent log entries 097 */ 098 long startSession(String workflowName, String overlayName, String inventoryName, int nodeCount); 099 100 /** 101 * Starts a new workflow execution session with full execution context. 102 * 103 * @param workflowName name of the workflow being executed 104 * @param overlayName name of the overlay being used (may be null) 105 * @param inventoryName name of the inventory file being used (may be null) 106 * @param nodeCount number of nodes participating in this session 107 * @param cwd current working directory 108 * @param gitCommit git commit hash of the workflow directory (may be null) 109 * @param gitBranch git branch name (may be null) 110 * @param commandLine the command line used to invoke actor-IaC 111 * @param actorIacVersion actor-IaC version 112 * @param actorIacCommit actor-IaC git commit hash (may be null) 113 * @return session ID for subsequent log entries 114 */ 115 default long startSession(String workflowName, String overlayName, String inventoryName, int nodeCount, 116 String cwd, String gitCommit, String gitBranch, 117 String commandLine, String actorIacVersion, String actorIacCommit) { 118 // Default implementation for backward compatibility 119 return startSession(workflowName, overlayName, inventoryName, nodeCount); 120 } 121 122 /** 123 * Records a log entry. 124 * 125 * @param sessionId session ID from startSession() 126 * @param nodeId identifier of the node generating this log 127 * @param level log level 128 * @param message log message 129 */ 130 void log(long sessionId, String nodeId, LogLevel level, String message); 131 132 /** 133 * Records a log entry with transition context. 134 * 135 * @param sessionId session ID from startSession() 136 * @param nodeId identifier of the node 137 * @param label current label in workflow 138 * @param level log level 139 * @param message log message 140 */ 141 void log(long sessionId, String nodeId, String label, LogLevel level, String message); 142 143 /** 144 * Records an action result. 145 * 146 * @param sessionId session ID 147 * @param nodeId node identifier 148 * @param label label 149 * @param actionName action/method name 150 * @param exitCode command exit code (0 for success) 151 * @param durationMs execution duration in milliseconds 152 * @param output command output or result message 153 */ 154 void logAction(long sessionId, String nodeId, String label, 155 String actionName, int exitCode, long durationMs, String output); 156 157 /** 158 * Marks a node as succeeded in this session. 159 * 160 * @param sessionId session ID 161 * @param nodeId node identifier 162 */ 163 void markNodeSuccess(long sessionId, String nodeId); 164 165 /** 166 * Marks a node as failed in this session. 167 * 168 * @param sessionId session ID 169 * @param nodeId node identifier 170 * @param reason failure reason 171 */ 172 void markNodeFailed(long sessionId, String nodeId, String reason); 173 174 /** 175 * Ends a session with the given status. 176 * 177 * @param sessionId session ID 178 * @param status final status 179 */ 180 void endSession(long sessionId, SessionStatus status); 181 182 /** 183 * Retrieves all log entries for a specific node in a session. 184 * 185 * @param sessionId session ID 186 * @param nodeId node identifier 187 * @return list of log entries 188 */ 189 List<LogEntry> getLogsByNode(long sessionId, String nodeId); 190 191 /** 192 * Retrieves log entries filtered by level. 193 * 194 * @param sessionId session ID 195 * @param minLevel minimum log level to include 196 * @return list of log entries 197 */ 198 List<LogEntry> getLogsByLevel(long sessionId, LogLevel minLevel); 199 200 /** 201 * Retrieves error logs for a session. 202 * 203 * @param sessionId session ID 204 * @return list of error log entries 205 */ 206 default List<LogEntry> getErrors(long sessionId) { 207 return getLogsByLevel(sessionId, LogLevel.ERROR); 208 } 209 210 /** 211 * Gets a summary of the session. 212 * 213 * @param sessionId session ID 214 * @return session summary 215 */ 216 SessionSummary getSummary(long sessionId); 217 218 /** 219 * Gets the most recent session ID. 220 * 221 * @return latest session ID, or -1 if no sessions exist 222 */ 223 long getLatestSessionId(); 224 225 /** 226 * Lists all sessions. 227 * 228 * @param limit maximum number of sessions to return 229 * @return list of session summaries 230 */ 231 List<SessionSummary> listSessions(int limit); 232}