package org.lognavigator.service; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.SequenceInputStream; import java.util.Date; import java.util.Set; import java.util.TreeSet; import org.lognavigator.bean.FileInfo; import org.lognavigator.bean.LogAccessConfig; import org.lognavigator.bean.OsType; import org.lognavigator.bean.LogAccessConfig.LogAccessType; import org.lognavigator.exception.LogAccessException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.util.FileCopyUtils; import org.springframework.util.StringUtils; /** * Service which manages access to logs on local host */ @Service @Qualifier("local") public class LocalLogAccessService extends AbstractShellLogAccessService implements LogAccessService { private static final String OS_NAME_SYSTEM_PROPERTY = "os.name"; private static final String WINDOWS_OS_MARKER = "windows"; private static final String AIX_OS_MARKER = "aix"; @Override public InputStream executeCommand(String logAccessConfigId, String shellCommand) throws LogAccessException { // Get the LogAccessConfig LogAccessConfig logAccessConfig = configService.getLogAccessConfig(logAccessConfigId); try { // Add the precommand (if any) if (StringUtils.hasText(logAccessConfig.getPreCommand())) { shellCommand = logAccessConfig.getPreCommand() + " && " + shellCommand; } // Prepare shellCommand array (depending OS) String[] shellCommandArray = null; if (getOSType(logAccessConfig) == OsType.WINDOWS) { shellCommandArray = new String[]{"cmd", "/C", shellCommand}; } else { shellCommandArray = new String[]{"/bin/sh", "-c", shellCommand}; } // Execute the command File currentDirectory = (logAccessConfig.getDirectory() != null) ? new File(logAccessConfig.getDirectory()) : null; Process process = Runtime.getRuntime().exec(shellCommandArray, null, currentDirectory); // Get and return the result stream InputStream resultStream = process.getInputStream(); InputStream errorStream = process.getErrorStream(); InputStream sequenceStream = new SequenceInputStream(resultStream, errorStream); return sequenceStream; } catch (IOException e) { if (e.getMessage().matches("Cannot run program \".+\" \\(in directory \".*\"\\).*")) { throw new LogAccessException("Configuration is invalid : directory " + logAccessConfig.getDirectory() + " does not exist", e); } else { throw new LogAccessException("Error when executing command " + shellCommand + " to " + logAccessConfig, e); } } } @Override public void downloadFile(String logAccessConfigId, String fileName, OutputStream downloadOutputStream) throws LogAccessException { // Get the LogAccessConfig LogAccessConfig logAccessConfig = configService.getLogAccessConfig(logAccessConfigId); // Execute the download try { File downloadFile = new File(logAccessConfig.getDirectory() + "/" + fileName); FileCopyUtils.copy(new FileInputStream(downloadFile), downloadOutputStream); } catch (IOException e) { throw new LogAccessException("Error when executing downloading " + fileName + " on " + logAccessConfig, e); } } @Override protected Set<FileInfo> listFilesUsingNativeSystem(LogAccessConfig logAccessConfig, String subPath) throws LogAccessException { // Define target directory String targetPath = logAccessConfig.getDirectory(); if (subPath != null) { targetPath += "/" + subPath; } File targetDirectory = new File(targetPath); // Check target directory if (!targetDirectory.exists()) { throw new LogAccessException("Directory '" + targetPath + "' does not exist"); } if (!targetDirectory.isDirectory()) { throw new LogAccessException("'" + targetPath + "' is not a directory"); } // List sub files and folders File[] childrenFiles = targetDirectory.listFiles(); // Extract meta-informations Set<FileInfo> fileInfos = new TreeSet<FileInfo>(); for (File childrenFile : childrenFiles) { FileInfo fileInfo = new FileInfo(); fileInfo.setFileName(childrenFile.getName()); fileInfo.setRelativePath(childrenFile.getPath().substring(logAccessConfig.getDirectory().length() + 1).replace('\\', '/')); fileInfo.setDirectory(childrenFile.isDirectory()); fileInfo.setLastModified(new Date(childrenFile.lastModified())); fileInfo.setFileSize(childrenFile.isDirectory() ? 0L : childrenFile.length()); fileInfo.setLogAccessType(LogAccessType.LOCAL); fileInfos.add(fileInfo); } // Return meta-informations about files and folders return fileInfos; } @Override protected OsType getOSType(LogAccessConfig logAccessConfig) { if (logAccessConfig.getOsType() == null) { OsType osType; String osName = System.getProperty(OS_NAME_SYSTEM_PROPERTY).toLowerCase(); // Check if OS is windows if (osName.contains(WINDOWS_OS_MARKER)) { osType = OsType.WINDOWS; } // Check if OS is AIX else if (osName.contains(AIX_OS_MARKER)) { osType = OsType.AIX; } // By default, OS is considered linux-compliant else { osType = OsType.LINUX; } // Update logAccessConfig to cache the information (and not execute command every time) logAccessConfig.setOsType(osType); } return logAccessConfig.getOsType(); } }