
io.sealights.agents.plugin.upgrade.AbstractUpgradeManager Maven / Gradle / Ivy
package io.sealights.agents.plugin.upgrade;
import io.sealights.agents.plugin.entities.Version;
import io.sealights.agents.plugin.upgrade.entities.AgentInfo;
import io.sealights.agents.plugin.upgrade.entities.UpgradeConfiguration;
import io.sealights.agents.plugin.upgrade.entities.UpgradeResponse;
import io.sealights.agents.plugin.upgrade.services.UpgradeProxy;
import io.sealights.agents.plugin.upgrade.utils.ArchiveUtils;
import io.sealights.agents.plugin.upgrade.utils.FileAndFolderUtils;
import io.sealights.agents.plugin.upgrade.utils.JarUtils;
import io.sealights.agents.plugin.upgrade.utils.UserMessageHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.jar.JarFile;
import static io.sealights.agents.plugin.upgrade.ComponentName.BUILD_SCANNER_COMPONENT_NAME;
import static io.sealights.agents.plugin.upgrade.ComponentName.TEST_LISTENER_COMPONENT_NAME;
/**
* Created by shahar on 7/31/2016.
*/
public abstract class AbstractUpgradeManager {
private UpgradeProxy upgradeProxy;
protected UpgradeConfiguration upgradeConfiguration;
protected final UserMessageHelper userMessageHelper;
private static final int VERSIONS_HISTORY_TO_SAVE_BESIDE_RECOMMENDED = 2;
public static final String SL_RELATIVE_CACHE_FOLDER = "sl-cache";
public static final String MAVEN_PLUGIN_AGENTS_RELATIVE_CACHE_FOLDER = "maven-plugin";
protected String embeddedVersion;
public AbstractUpgradeManager(UpgradeProxy upgradeProxy, UpgradeConfiguration upgradeConfiguration, UserMessageHelper userMessageHelper) {
this.upgradeProxy = upgradeProxy;
this.upgradeConfiguration = upgradeConfiguration;
this.userMessageHelper = userMessageHelper;
this.embeddedVersion = AbstractUpgradeManager.class.getPackage().getImplementationVersion();
}
/**
* Ensures that the latest version of the agent is present locally (downloads it if needed)
*
* @return the path to the JAR file
* @throws Exception When the server could not be contacted or various IO exceptions (permissions, network, etc.)
*/
public String ensureLatestAgentPresentLocally(){
try {
UpgradeResponse upgradeResponse = upgradeProxy.getRecommendedVersion("sealights-java");
if (!isValidResponse(upgradeResponse)) {
throw new Exception("Could not get latest version info from server. " +
"The response from the server has invalid fields.");
}
String jarsFolder = FileAndFolderUtils.join(upgradeConfiguration.getFilesStorage(),
SL_RELATIVE_CACHE_FOLDER, MAVEN_PLUGIN_AGENTS_RELATIVE_CACHE_FOLDER);
if (!FileAndFolderUtils.verifyFolderExists(jarsFolder)){
throw new Exception("Could not verify that cache folder exists: '" + jarsFolder + "'.");
}
String foundAgent = findOrDownloadAgentByVersion(jarsFolder, upgradeResponse);
return foundAgent;
} catch (FileNotFoundException e) {
throw new RuntimeException("Error while trying to resolve Sealights recommended agents version. " +
"Probably the server did not found recommended agents version.");
}
catch (Exception e) {
throw new RuntimeException("Error while trying to resolve Sealights recommended agents version.", e);
}
}
/*
* Response will be valid if:
* 1. Version is in the right format.
* 2. The agent name can be found in the ComponentName enum.
* We don't check if url is malformed because maybe download won't be needed.
* */
private boolean isValidResponse(UpgradeResponse upgradeResponse) {
boolean isValid = true;
if (upgradeResponse == null) {
userMessageHelper.printWarn("Got response 'null'.");
return false;
}
AgentInfo agentInfo = upgradeResponse.getAgent();
if (agentInfo == null) {
userMessageHelper.printWarn("Got response with agent information 'null'.");
return false;
}
if (!Version.isValidVersion(agentInfo.getVersion())) {
userMessageHelper.printWarn("Got response with invalid version '" + agentInfo.getVersion() + "'.");
isValid = false;
}
if (!isValidAgentName(agentInfo.getName())) {
userMessageHelper.printWarn("Got response with invalid agent name '" + agentInfo.getName() + "'.");
isValid = false;
}
return isValid;
}
private boolean isValidAgentName(String name) {
return "sealights-java".equals(name);
}
private void rearrangeJarsFolder(String jarsFolder) {
File folder = new File(jarsFolder);
File[] filesInFolder = folder.listFiles();
if (filesInFolder == null){
userMessageHelper.printWarn("Unable to rearrange the cache folder since 'filesInFolder' is null.");
return;
}
TreeMap> versions = createAgentsVersionsSortedMap(filesInFolder);
if (versions.size() > VERSIONS_HISTORY_TO_SAVE_BESIDE_RECOMMENDED) {
performJarsRearrangement(versions);
}
}
private void performJarsRearrangement(TreeMap> versions) {
versions = getVersionsToDelete(versions);
Iterator it = versions.entrySet().iterator();
while (it.hasNext()) {
Map.Entry> pair = (Map.Entry>) it.next();
List agentsToDelete = pair.getValue();
for (File agent : agentsToDelete)
tryDeleteFile(agent, "old agent");
}
}
private TreeMap> getVersionsToDelete(TreeMap> versions) {
for (int i = 0; i < VERSIONS_HISTORY_TO_SAVE_BESIDE_RECOMMENDED; i++) {
versions.remove(versions.lastKey());
}
return versions;
}
private TreeMap> createAgentsVersionsSortedMap(File[] filesInFolder) {
TreeMap> versionsTree = new TreeMap<>();
for (File f : filesInFolder) {
if (f == null || !f.isFile())
continue;
String filename = f.getName();
boolean isAgentJar = filename.startsWith("sl-") && filename.endsWith(".jar");
if (!isAgentJar)
continue;
String detectedVersion = detectVersionFromAgentFileName(filename);
if (!Version.isValidVersion(detectedVersion)){
continue;
}
Version v = new Version(detectedVersion);
addAgentToVersionAgentTree(versionsTree, v, f);
}
return versionsTree;
}
private String detectVersionFromAgentFileName(String fileName) {
fileName = fileName.replace(BUILD_SCANNER_COMPONENT_NAME.toString() + "-", "");
fileName = fileName.replace(TEST_LISTENER_COMPONENT_NAME.toString() + "-", "");
return fileName.replace(".jar", "");
}
private void addAgentToVersionAgentTree(TreeMap> versionsTree, Version version, File agent) {
List listToAdd = tryGetMatchingVersionInVersionAgentTree(versionsTree, version);
if (listToAdd != null) {
listToAdd.add(agent);
} else {
//create new version key
List filesRelatedToVersion = new ArrayList<>();
filesRelatedToVersion.add(agent);
versionsTree.put(version, filesRelatedToVersion);
}
}
private List tryGetMatchingVersionInVersionAgentTree(TreeMap> versionsTree, Version version) {
for (Version v : versionsTree.keySet()) {
if (v.equals(version))
return versionsTree.get(v);
}
return null;
}
/**
* Based on (@link upgradeResponse), checks if the file exists. If it doesn't, it downloads the file.
*
* @param jarsFolder Cache folder where agents are stored
* @param upgradeResponse
* @return Agent Jar file path
* @throws Exception
*/
protected String findOrDownloadAgentByVersion(String jarsFolder, UpgradeResponse upgradeResponse) {
JarFile jarFile;
AgentInfo agentInfo = upgradeResponse.getAgent();
String recommendedVersion = agentInfo.getVersion();
userMessageHelper.println("Check if agent '" + getComponentName()
+ " with version '" + recommendedVersion + "' exists in files storage.");
jarFile = tryGetRecommendedAgentFromFolder(jarsFolder, recommendedVersion);
if (jarFile != null) {
userMessageHelper.println("Found '" + getComponentName()
+ "' with version '" + recommendedVersion + "' in files storage.");
return jarFile.getName();
}
userMessageHelper.println("Trying to get agent '" + getComponentName()
+ "' with version '" + recommendedVersion + "' from remote storage.");
jarFile = tryGetRecommendedAgentFromServer(jarsFolder, upgradeResponse);
if (jarFile != null) {
userMessageHelper.println("'" + getComponentName() + "' with version '" + recommendedVersion + "' has been downloaded.");
return jarFile.getName();
}
throw new RuntimeException("Could not download latest agent version.");
}
protected JarFile tryGetRecommendedAgentFromServer(String jarsFolder, UpgradeResponse upgradeResponse){
AgentInfo agentInfo = upgradeResponse.getAgent();
if (agentInfo == null){
userMessageHelper.printError("Unable to get recommended agent from server. " +
"Recommended agent information was 'null'.");
return null;
}
String version = agentInfo.getVersion();
String url = agentInfo.getUrl();
String zipFilePath = getAgentsTargetZipFilePath(jarsFolder);
// try to download the agent to the target zip file.
userMessageHelper.println("Trying to upgrade to version '" + version + "' from url '" + url + "'.");
if (!upgradeProxy.downloadAgent(url, zipFilePath)) {
userMessageHelper.printWarn("Failed to download agent with version '" + version + "'.");
}else{
userMessageHelper.println("Download completed successfully.");
rearrangeJarsFolder(jarsFolder);
// try to unzip the downloaded agent.
ArchiveUtils archiveUtils = new ArchiveUtils(userMessageHelper);
archiveUtils.unzip(zipFilePath, jarsFolder);
tryDeleteDownloadedZip(zipFilePath);
File newAgent = getPathToDownloadedAgent(jarsFolder, version);
if (newAgent.isFile())
return createTempJarFileFromExternalJar(newAgent);
userMessageHelper.printWarn("Failed to unzip agent with version '" + version + "'.");
}
return null;
}
protected JarFile tryGetRecommendedAgentFromFolder(String jarsFolder, String recommendedVersion) {
String jarNameToFind = getComponentNameDash() + recommendedVersion + ".jar";
File recommendedAgent = FileAndFolderUtils.findFileInFolder(jarsFolder, jarNameToFind);
if (recommendedAgent == null){
userMessageHelper.println("Didn't find the recommended agent '" + jarNameToFind
+ "' in folder '" + jarsFolder + "'.");
return null;
}
if (!recommendedAgent.isFile()) {
userMessageHelper.println("Didn't find the recommended agent '"
+ recommendedAgent.getAbsolutePath() + "' in file system or it is not a valid file.");
return null;
}
return createTempJarFileFromExternalJar(recommendedAgent);
}
private void tryDeleteDownloadedZip(String zipFilePath){
File zipFileToDelete = new File(zipFilePath);
tryDeleteFile(zipFileToDelete, "agent zip file");
}
private String getAgentsTargetZipFilePath(String jarsFolder){
String fileName = getFileToDownloadName() + ".zip";
return FileAndFolderUtils.join(jarsFolder, fileName);
}
private File getPathToDownloadedAgent(String jarsFolder, String version) {
Version recommendedVersion = new Version(version);
String newAgentName = getComponentNameDash() + recommendedVersion.get() + ".jar";
String pathToNewAgent = FileAndFolderUtils.join(jarsFolder, newAgentName);
return new File(pathToNewAgent);
}
protected JarFile createTempJarFileFromExternalJar(File recommendedAgent){
String agentPath = upgradeConfiguration.getFilesStorage();
return loadExternalJar(recommendedAgent, agentPath, false);
}
protected JarFile loadExternalJar(File recommendedAgent, String agentPath, boolean useOverrideListenerPath){
return JarUtils.loadExternalJar(recommendedAgent, getComponentName(),
userMessageHelper, agentPath, useOverrideListenerPath);
}
private void tryDeleteFile(File oldAgent, String descriptor) {
try {
if (oldAgent.delete()) {
userMessageHelper.println("Successfully deleted " + descriptor + ": '" + oldAgent.getAbsolutePath() + "'.");
return;
}
if (oldAgent.exists()) {
userMessageHelper.println("Failed to delete " + descriptor + ": '" + oldAgent.getAbsolutePath() + "'.");
}
} catch (Exception e) {
userMessageHelper.printError("Failed to delete " + descriptor + ": '" + oldAgent.getAbsolutePath() + "'. Error: ", e);
}
}
abstract protected ComponentName getComponentNameEnum();
abstract String getFileToDownloadName();
protected String getComponentName() {
return getComponentNameEnum().toString();
}
private String getComponentNameDash() {
return getComponentName() + "-";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy