App publishing improvements

remotes/1720607823028358574/master^2
Rajitha Kumara 7 months ago
parent 99e7d12ab7
commit 1576ef86d0

@ -25,16 +25,52 @@ public class ApplicationArtifact {
private String installerName;
private InputStream installerStream;
private String installerPath;
private String bannerName;
private InputStream bannerStream;
private String bannerPath;
private String iconName;
private InputStream iconStream;
private String iconPath;
private Map<String , InputStream> screenshots;
private Map<String, String> screenshotPaths;
public String getInstallerPath() {
return installerPath;
}
public void setInstallerPath(String installerPath) {
this.installerPath = installerPath;
}
public String getBannerPath() {
return bannerPath;
}
public void setBannerPath(String bannerPath) {
this.bannerPath = bannerPath;
}
public String getIconPath() {
return iconPath;
}
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public Map<String, String> getScreenshotPaths() {
return screenshotPaths;
}
public void setScreenshotPaths(Map<String, String> screenshotPaths) {
this.screenshotPaths = screenshotPaths;
}
public String getInstallerName() {
return installerName;

@ -140,4 +140,14 @@ public interface ApplicationStorageManager {
* @throws ApplicationStorageManagementException thrown if
*/
void deleteAppFolderOfTenant(int tenantId) throws ApplicationStorageManagementException;
/**
* Get absolute path of a file describe by hashVal, folder, file name and tenantId
* @param hashVal Hash value of the application release.
* @param folderName Folder name file resides.
* @param fileName File name of the file.
* @param tenantId Tenant ID
* @return Absolute path
*/
String getAbsolutePathOfFile(String hashVal, String folderName, String fileName, int tenantId);
}

@ -102,11 +102,15 @@ import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.core.Response;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -727,20 +731,23 @@ public class ApplicationManagerImpl implements ApplicationManager {
throws ResourceManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
byte[] content = getByteContentOfApp(applicationArtifact);
String md5OfApp = generateMD5OfApp(applicationArtifact, content);
try {
String md5OfApp = applicationStorageManager.getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
validateReleaseBinaryFileHash(md5OfApp);
releaseDTO.setUuid(UUID.randomUUID().toString());
releaseDTO.setAppHashValue(md5OfApp);
releaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager.uploadReleaseArtifact(releaseDTO, deviceType,
binaryDuplicate, tenantId);
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
} catch (IOException e) {
String msg = "Error occurred when uploading release artifact into the server";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (StorageManagementException e) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ releaseDTO.getUuid();
log.error(msg, e);
}
return addImageArtifacts(releaseDTO, applicationArtifact, tenantId);
}
@ -856,15 +863,12 @@ public class ApplicationManagerImpl implements ApplicationManager {
String uuid = UUID.randomUUID().toString();
applicationReleaseDTO.setUuid(uuid);
// The application executable artifacts such as apks are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
if (!DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
.getAppInstallerData(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), deviceType);
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(applicationInstaller.getPackageName());
} else {
@ -892,7 +896,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new ApplicationManagementException(msg);
}
String md5OfApp = applicationStorageManager.getMD5(new ByteArrayInputStream(content));
String md5OfApp = applicationStorageManager.getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
@ -907,10 +911,9 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
applicationReleaseDTO.setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, tenantId);
}
.uploadReleaseArtifact(applicationReleaseDTO, deviceType,
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
} catch (StorageManagementException e) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
@ -929,9 +932,8 @@ public class ApplicationManagerImpl implements ApplicationManager {
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
} catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
String msg = "Error occurred when getting file input stream. Installer name: " + applicationArtifact
.getInstallerName();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
@ -957,23 +959,18 @@ public class ApplicationManagerImpl implements ApplicationManager {
// The application executable artifacts such as apks are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = applicationStorageManager.getMD5(binaryClone);
String md5OfApp = applicationStorageManager.getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application "
+ "release UUID " + applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (!applicationReleaseDTO.getAppHashValue().equals(md5OfApp)) {
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
.getAppInstallerData(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), deviceType);
String packageName = applicationInstaller.getPackageName();
try {
@ -1003,13 +1000,11 @@ public class ApplicationManagerImpl implements ApplicationManager {
applicationReleaseDTO.setPackageName(packageName);
String deletingAppHashValue = applicationReleaseDTO.getAppHashValue();
applicationReleaseDTO.setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate,
applicationStorageManager.uploadReleaseArtifact(applicationReleaseDTO, deviceType,
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())),
tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO, tenantId);
}
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application "
+ "release existing for new app hash value.";
@ -1024,15 +1019,13 @@ public class ApplicationManagerImpl implements ApplicationManager {
ConnectionManagerUtil.closeDBConnection();
}
}
}
}
} catch (StorageManagementException e) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application "
+ "release UUID " + applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
String msg = "Error occurred when getting file input stream. Installer name: " + applicationArtifact
.getInstallerName();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
@ -3607,15 +3600,15 @@ public class ApplicationManagerImpl implements ApplicationManager {
DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
// The application executable artifacts such as deb are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = applicationStorageManager.getMD5(binaryClone);
String md5OfApp = applicationStorageManager.getMD5(
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (!applicationReleaseDTO.get().getAppHashValue().equals(md5OfApp)) {
try {
ConnectionManagerUtil.getDBConnection();
@ -3632,13 +3625,11 @@ public class ApplicationManagerImpl implements ApplicationManager {
applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName());
String deletingAppHashValue = applicationReleaseDTO.get().getAppHashValue();
applicationReleaseDTO.get().setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO.get(), deviceTypeObj.getName(),
binaryDuplicate, tenantId);
applicationStorageManager.
uploadReleaseArtifact(applicationReleaseDTO.get(), deviceTypeObj.getName(),
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO.get(), tenantId);
}
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application"
+ " release existing for new app hash value.";
@ -3654,7 +3645,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
ConnectionManagerUtil.closeDBConnection();
}
}
}
} catch (StorageManagementException e) {
String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid();

@ -37,6 +37,7 @@ import io.entgra.device.mgt.core.device.mgt.core.common.exception.StorageManagem
import io.entgra.device.mgt.core.device.mgt.core.common.util.StorageManagementUtil;
import java.io.*;
import java.nio.file.Paths;
import java.util.List;
import static io.entgra.device.mgt.core.device.mgt.core.common.util.StorageManagementUtil.saveFile;
@ -155,13 +156,13 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
public void uploadReleaseArtifact(ApplicationReleaseDTO applicationReleaseDTO,
String deviceType, InputStream binaryFile, int tenantId) throws ResourceManagementException {
try {
byte [] content = IOUtils.toByteArray(binaryFile);
//byte [] content = IOUtils.toByteArray(binaryFile);
String artifactDirectoryPath =
storagePath + tenantId + File.separator + applicationReleaseDTO.getAppHashValue() + File.separator
+ Constants.APP_ARTIFACT;
StorageManagementUtil.createArtifactDirectory(artifactDirectoryPath);
String artifactPath = artifactDirectoryPath + File.separator + applicationReleaseDTO.getInstallerName();
saveFile(new ByteArrayInputStream(content), artifactPath);
saveFile(binaryFile, artifactPath);
} catch (IOException e) {
String msg = "IO Exception while saving the release artifacts in the server for the application UUID "
+ applicationReleaseDTO.getUuid();
@ -324,4 +325,12 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
}
}
}
@Override
public String getAbsolutePathOfFile(String hashVal, String folderName, String fileName, int tenantId) {
String filePath =
storagePath + tenantId + File.separator + hashVal + File.separator + folderName + File.separator
+ fileName;
return Paths.get(filePath).toAbsolutePath().toString();
}
}

@ -181,6 +181,7 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(artifactLinkUrl).download(artifactLinkUrl);
applicationArtifact.setInstallerName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setInstallerStream(fileDescriptor.getFile());
applicationArtifact.setInstallerPath(fileDescriptor.getAbsolutePath());
}
if (iconLink != null) {
@ -188,6 +189,7 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(iconLinkUrl).download(iconLinkUrl);
applicationArtifact.setIconName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setIconStream(fileDescriptor.getFile());
applicationArtifact.setIconPath(fileDescriptor.getAbsolutePath());
}
if (bannerLink != null) {
@ -195,10 +197,12 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(bannerLinkUrl).download(bannerLinkUrl);
applicationArtifact.setBannerName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setBannerStream(fileDescriptor.getFile());
applicationArtifact.setBannerPath(fileDescriptor.getAbsolutePath());
}
if (screenshotLinks != null) {
Map<String, InputStream> screenshotData = new TreeMap<>();
Map<String, String> screenshotPaths = new TreeMap<>();
// This is to handle cases in which multiple screenshots have the same name
Map<String, Integer> screenshotNameCount = new HashMap<>();
URL screenshotLinkUrl;
@ -209,6 +213,7 @@ public class ApplicationManagementUtil {
screenshotNameCount.put(screenshotName, screenshotNameCount.getOrDefault(screenshotName, 0) + 1);
screenshotName = FileUtil.generateDuplicateFileName(screenshotName, screenshotNameCount.get(screenshotName));
screenshotData.put(screenshotName, fileDescriptor.getFile());
screenshotPaths.put(screenshotName, fileDescriptor.getAbsolutePath());
}
applicationArtifact.setScreenshots(screenshotData);
}

@ -23,7 +23,9 @@ import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.ChunkDescriptor;
import io.entgra.device.mgt.core.application.mgt.common.FileDescriptor;
import io.entgra.device.mgt.core.application.mgt.common.FileMetaEntry;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationStorageManagementException;
import io.entgra.device.mgt.core.application.mgt.core.exception.FileTransferServiceHelperUtilException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.NotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -175,6 +177,12 @@ public class FileTransferServiceHelperUtil {
}
String []urlPathSegments = downloadUrl.getPath().split("/");
FileDescriptor fileDescriptorResolvedFromRelease = resolve(urlPathSegments);
if (fileDescriptorResolvedFromRelease != null) {
return fileDescriptorResolvedFromRelease;
}
if (urlPathSegments.length < 2) {
if (log.isDebugEnabled()) {
log.debug("URL patch segments contain less than 2 segments");
@ -234,4 +242,53 @@ public class FileTransferServiceHelperUtil {
throw new FileTransferServiceHelperUtilException("Error encountered while creating artifact file", e);
}
}
private static FileDescriptor resolve(String []urlSegments) throws FileTransferServiceHelperUtilException {
if (urlSegments.length < 4) {
if (log.isDebugEnabled()) {
log.debug("URL path segments contain less than 2 segments");
}
return null;
}
int tenantId;
try {
tenantId = Integer.parseInt(urlSegments[urlSegments.length - 4]);
} catch (NumberFormatException e) {
if (log.isDebugEnabled()) {
log.debug("URL isn't pointing to a file resides in the default storage path");
}
return null;
}
String fileName = urlSegments[urlSegments.length - 1];
String folderName = urlSegments[urlSegments.length - 2];
String appHash = urlSegments[urlSegments.length - 3];
try {
InputStream fileStream = DataHolder.getInstance().
getApplicationStorageManager().getFileStream(appHash, folderName, fileName, tenantId);
if (fileStream == null) {
if (log.isDebugEnabled()) {
log.debug("Could not found the file " + fileName);
}
return null;
}
String []fileNameSegments = fileName.split("\\.(?=[^.]+$)");
if (fileNameSegments.length < 2) {
throw new FileTransferServiceHelperUtilException("Invalid full qualified name encountered :" + fileName);
}
FileDescriptor fileDescriptor = new FileDescriptor();
fileDescriptor.setFile(fileStream);
fileDescriptor.setFullQualifiedName(fileName);
fileDescriptor.setExtension(fileNameSegments[fileNameSegments.length - 1]);
fileDescriptor.setFileName(fileNameSegments[fileNameSegments.length - 2]);
fileDescriptor.setAbsolutePath(DataHolder.getInstance().
getApplicationStorageManager().getAbsolutePathOfFile(appHash, folderName, fileName, tenantId));
return fileDescriptor;
} catch (ApplicationStorageManagementException e) {
throw new FileTransferServiceHelperUtilException("Error encountered while getting file input stream", e);
}
}
}

@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.device.mgt.core.common.exception.StorageManagementException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -31,6 +33,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* This is a util class that handles Storage Management related tasks.
@ -87,13 +90,14 @@ public class StorageManagementUtil {
* @param path Path the file need to be saved in.
*/
public static void saveFile(InputStream inputStream, String path) throws IOException {
try (OutputStream outStream = new FileOutputStream(new File(path))) {
byte[] buffer = new byte[inputStream.available()];
if (inputStream.read(buffer) != -1) {
outStream.write(buffer);
try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(Files.newOutputStream(Paths.get(path)));
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
byte []buffer = new byte[8192];
int n;
while ((n = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, n);
}
} finally {
inputStream.close();
bufferedOutputStream.flush();
}
}

Loading…
Cancel
Save