Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor storage system #319

Merged
merged 5 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.microsoft.hydralab.common.monitor.MetricPushGateway;
import com.microsoft.hydralab.common.util.ADBOperateUtil;
import com.microsoft.hydralab.common.util.Const;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import io.micrometer.core.instrument.MeterRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;
Expand All @@ -33,6 +33,7 @@
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand Down Expand Up @@ -97,10 +98,8 @@ public AgentWebSocketClient agentWebSocketClient(AgentWebSocketClientService age
}

@Bean
public DeviceManager initDeviceManager(BlobStorageClient deviceLabBlobClient, ADBOperateUtil adbOperateUtil,
AppiumServerManager appiumServerManager,
public DeviceManager initDeviceManager(StorageServiceClientProxy storageServiceClientProxy, ADBOperateUtil adbOperateUtil, AppiumServerManager appiumServerManager,
DeviceStatusListenerManager deviceStatusListenerManager) {

AgentType agentType = AgentType.formAgentType(agentTypeValue);
DeviceManager deviceManager = agentType.getManager();
if (deviceManager instanceof AndroidDeviceManager) {
Expand Down Expand Up @@ -135,7 +134,7 @@ public DeviceManager initDeviceManager(BlobStorageClient deviceLabBlobClient, AD
}
}
deviceManager.setDeviceLogBaseDir(deviceLogBaseDir);
deviceManager.setBlobStorageClient(deviceLabBlobClient);
deviceManager.setStorageServiceClientProxy(storageServiceClientProxy);

deviceManager.setScreenshotDir(getScreenshotDir());
deviceManager.setDeviceFolderUrlPrefix(AppOptions.DEVICE_STORAGE_MAPPING_REL_PATH);
Expand Down Expand Up @@ -172,11 +171,6 @@ public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
return fastConverter;
}

@Bean
public BlobStorageClient blobStorageClient() {
return new BlobStorageClient();
}

@Bean
public SmartTestUtil smartTestUtil() {
return new SmartTestUtil(appOptions.getLocation());
Expand Down Expand Up @@ -225,4 +219,9 @@ public PrometheusPushGatewayManager monitorPrometheusPushGatewayManager(PushGate
return new PrometheusPushGatewayManager(pushGateway, registry,
pushRate, job, groupingKey, shutdownOperation);
}

@Bean
public StorageServiceClientProxy storageServiceClientProxy(ApplicationContext applicationContext) {
return new StorageServiceClientProxy(applicationContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import com.microsoft.hydralab.common.management.impl.IOSDeviceManager;
import com.microsoft.hydralab.common.util.CommandOutputReceiver;
import com.microsoft.hydralab.common.util.Const;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import com.microsoft.hydralab.common.util.ThreadPoolUtil;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
Expand All @@ -32,14 +32,13 @@ public class AgentManageService {
@Resource
private AppOptions appOptions;
@Resource
BlobStorageClient blobStorageClient;
StorageServiceClientProxy storageServiceClientProxy;

public void updateAgentPackage(AgentUpdateTask updateTask, String path) {
Runnable run = () -> {
sendMessageToCenter(true, "Download package file.", "", path);
File downloadToFile = new File(appOptions.getLocation(), updateTask.getPackageInfo().getFileName());
blobStorageClient.downloadFileFromBlob(downloadToFile, updateTask.getPackageInfo().getBlobContainer(),
updateTask.getPackageInfo().getBlobPath());
storageServiceClientProxy.download(downloadToFile, updateTask.getPackageInfo());
sendMessageToCenter(true, "Download Package Success!", "", path);

restartAgent(updateTask.getPackageInfo().getFileName(), path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import com.microsoft.hydralab.common.monitor.MetricPushGateway;
import com.microsoft.hydralab.common.util.Const;
import com.microsoft.hydralab.common.util.GlobalConstant;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import com.microsoft.hydralab.common.util.ThreadUtils;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory;
Expand Down Expand Up @@ -54,14 +54,15 @@ public class AgentWebSocketClientService implements TestTaskRunCallback {
@Resource
AgentManageService agentManageService;
@Resource
BlobStorageClient blobStorageClient;
MeterRegistry meterRegistry;
AgentUser agentUser;
@Resource
private StorageServiceClientProxy storageServiceClientProxy;
private boolean isStorageClientInit = false;
@Resource
private AppOptions appOptions;
@Resource
private AgentWebSocketClient agentWebSocketClient;
@Resource
MeterRegistry meterRegistry;
AgentUser agentUser;
@Value("${agent.version}")
private String versionName;
@Value("${agent.versionCode}")
Expand Down Expand Up @@ -169,16 +170,14 @@ public void onMessage(Message message) {

private void heartbeatResponse(Message message) {
AgentMetadata agentMetadata = (AgentMetadata) message.getBody();
blobStorageClient.setSASData(agentMetadata.getBlobSAS());
syncAgentStatus(agentMetadata.getAgentUser());
if (isPrometheusEnabled && !pushGateway.isBasicAuthSet.get()) {
pushGateway.setConnectionFactory(
new BasicAuthHttpConnectionFactory(agentMetadata.getPushgatewayUsername(),
agentMetadata.getPushgatewayPassword()));
ThreadUtils.safeSleep(1000);
pushGateway.isBasicAuthSet.set(true);
log.info("Pushgateway has set basic auth now, data can be pushed correctly.");

if (!isStorageClientInit) {
storageServiceClientProxy.initAgentStorageClient(agentMetadata.getStorageType());
isStorageClientInit = true;
}
storageServiceClientProxy.updateAccessToken(agentMetadata.getAccessToken());
syncAgentStatus(agentMetadata.getAgentUser());
prometheusPushgatewayInit(agentMetadata);
}

private void syncAgentStatus(AgentUser passedAgent) {
Expand All @@ -187,6 +186,15 @@ private void syncAgentStatus(AgentUser passedAgent) {
agentUser.setBatteryStrategy(passedAgent.getBatteryStrategy());
}

private void prometheusPushgatewayInit(AgentMetadata agentMetadata) {
if (isPrometheusEnabled && !pushGateway.isBasicAuthSet.get()) {
pushGateway.setConnectionFactory(new BasicAuthHttpConnectionFactory(agentMetadata.getPushgatewayUsername(), agentMetadata.getPushgatewayPassword()));
ThreadUtils.safeSleep(1000);
pushGateway.isBasicAuthSet.set(true);
log.info("Pushgateway has set basic auth now, data can be pushed correctly.");
}
}

private void provideAuthInfo(Message message) {
Message responseAuth = new Message();
responseAuth.setSessionId(message.getSessionId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,12 @@ private StorageFileInfo saveFileToBlob(File file, File folder, Logger logger) {
StorageFileInfo storageFileInfo = new StorageFileInfo(file,
"test/result/" + folder.getParentFile().getName() + "/" + folder.getName(),
StorageFileInfo.FileType.COMMON_FILE);
return attachmentService.addFileInfo(storageFileInfo, file, EntityType.TEST_RESULT,
logger);
return attachmentService.saveFileInStorageAndDB(storageFileInfo, file, EntityType.TEST_RESULT, logger);
}

private void processAndSaveDeviceTestResultBlobUrl(TestRun result) {
Assert.isTrue(result.getAttachments().size() > 0, "deviceTestResultBlobUrl should not null");
String deviceTestResultBlobUrl = result.getAttachments().get(0).getBlobUrl();
String deviceTestResultBlobUrl = result.getAttachments().get(0).getCDNUrl();
String fileName = result.getAttachments().get(0).getFileName();
log.info("deviceTestResultBlobUrl is {}", deviceTestResultBlobUrl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.microsoft.hydralab.common.entity.common.TestTask;
import com.microsoft.hydralab.common.util.CommandOutputReceiver;
import com.microsoft.hydralab.common.util.FileUtil;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
Expand All @@ -28,7 +28,7 @@ public class FileLoadUtil {
@Resource
private AppOptions appOptions;
@Resource
BlobStorageClient blobStorageClient;
StorageServiceClientProxy storageServiceClientProxy;

public void clearAttachments(TestTask testTask) {
List<StorageFileInfo> attachments = testTask.getTestFileSet().getAttachments();
Expand Down Expand Up @@ -58,17 +58,17 @@ public void loadAttachments(TestTask testTask) {
loadCommonFile(attachment);
break;
case StorageFileInfo.FileType.APP_FILE:
File appFile = downloadFromBlob(attachment);
File appFile = downloadFile(attachment);
Assert.isTrue(appFile != null && appFile.exists(), "Download app file failed!");
testTask.setAppFile(appFile);
break;
case StorageFileInfo.FileType.TEST_APP_FILE:
File testAppFile = downloadFromBlob(attachment);
File testAppFile = downloadFile(attachment);
Assert.isTrue(testAppFile != null && testAppFile.exists(), "Download test app file failed!");
testTask.setTestAppFile(testAppFile);
break;
case StorageFileInfo.FileType.T2C_JSON_FILE:
File testJsonFile = downloadFromBlob(attachment);
File testJsonFile = downloadFile(attachment);
Assert.isTrue(testJsonFile != null && testJsonFile.exists(), "Download test json file failed!");
testTask.addTestJsonFile(testJsonFile);
break;
Expand All @@ -81,7 +81,7 @@ public void loadAttachments(TestTask testTask) {
public void installWinApp(StorageFileInfo attachment) {
try {
Runtime runtime = Runtime.getRuntime();
File attachmentFile = downloadFromBlob(attachment, appOptions.getTestPackageLocation(), attachment.getBlobPath());
File attachmentFile = downloadFile(attachment, appOptions.getTestPackageLocation(), attachment.getBlobPath());
String installCommand = "& { Add-AppxPackage -ForceApplicationShutdown -forceupdatefromanyversion -Path '" +
attachmentFile.getAbsolutePath() + "' }";
String[] command = new String[]{"Powershell.exe", "-Command", installCommand};
Expand All @@ -105,7 +105,7 @@ public void loadCommonFile(StorageFileInfo attachment) {
File loadFolder = new File(appOptions.getLocation() + "/" + attachment.getLoadDir());
Assert.isTrue(!loadFolder.exists(), "Load file error : folder has been existed!");
log.info("Load common file start filename:{} path:{}", attachment.getFileName(), loadFolder.getAbsolutePath());
File attachmentFile = downloadFromBlob(attachment, appOptions.getLocation(), attachment.getLoadDir() + "/" + attachment.getFileName());
File attachmentFile = downloadFile(attachment, appOptions.getLocation(), attachment.getLoadDir() + "/" + attachment.getFileName());
if (StorageFileInfo.LoadType.UNZIP.equalsIgnoreCase(attachment.getLoadType())) {
FileUtil.unzipFile(attachmentFile.getAbsolutePath(), loadFolder.getAbsolutePath());
}
Expand All @@ -115,17 +115,17 @@ public void loadCommonFile(StorageFileInfo attachment) {
}
}

private File downloadFromBlob(StorageFileInfo attachment, String location, String targetFilePath) throws IOException {
private File downloadFile(StorageFileInfo attachment, String location, String targetFilePath) throws IOException {
File file = new File(location, targetFilePath);
log.debug("download file from {} to {}", attachment.getBlobUrl(), file.getAbsolutePath());
blobStorageClient.downloadFileFromBlob(file, attachment.getBlobContainer(), attachment.getBlobPath());
storageServiceClientProxy.download(file, attachment);
return file;
}

private File downloadFromBlob(StorageFileInfo attachment) {
private File downloadFile(StorageFileInfo attachment) {
File file = null;
try {
file = downloadFromBlob(attachment, appOptions.getTestPackageLocation(), attachment.getBlobPath());
file = downloadFile(attachment, appOptions.getTestPackageLocation(), attachment.getBlobPath());
log.info("Download file success");
} catch (IOException e) {
log.error("Download file failed", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import com.microsoft.hydralab.agent.service.AgentWebSocketClientService;
import com.microsoft.hydralab.agent.socket.AgentWebSocketClient;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
Expand All @@ -30,7 +30,7 @@
public class BaseTest {
protected Logger baseLogger = LoggerFactory.getLogger(BaseTest.class);
@MockBean
BlobStorageClient blobStorageClient;
StorageServiceClientProxy storageServiceClientProxy;
@MockBean
AgentWebSocketClient agentWebSocketClient;
@MockBean
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ import com.microsoft.hydralab.compile.UMLImageGenerator

task generateUMLImage(group: 'documentation') {
doFirst {
def scanningDirList = ['agent/doc/UML', 'gradle_plugin/doc/UML']
def scanningDirList = ['agent/doc/UML', 'common/doc/UML', 'gradle_plugin/doc/UML']
def outputDir = new File(projectDir, 'docs/images/UML')

def generator = new UMLImageGenerator()
Expand Down
8 changes: 5 additions & 3 deletions center/application-sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ spring:
app:
# Mail Address Format
default-user: ${DEFAULT_USER}
blob:
connection: ${BLOB_CONNECTION_STR}
CDNUrl: ${CDN_URL}
storage:
type: ${STORAGE_TYPE:AZURE} # current available options: LOCAL, AZURE
blob:
connection: ${BLOB_CONNECTION_STR}
CDNUrl: ${CDN_URL}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.microsoft.hydralab.common.entity.center.BlobProperty;
import com.microsoft.hydralab.common.monitor.MetricPushGateway;
import com.microsoft.hydralab.common.util.blob.BlobStorageClient;
import com.microsoft.hydralab.common.util.Const;
import com.microsoft.hydralab.common.file.StorageServiceClientProxy;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory;
import io.prometheus.client.exporter.PushGateway;
Expand All @@ -18,6 +18,7 @@
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
Expand All @@ -37,6 +38,8 @@ public class AppConfig {
private String pushgatewayUsername;
@Value("${management.metrics.export.prometheus.pushgateway.password}")
private String pushgatewayPassword;
@Value("${app.storage.type}")
private String storageType;

@Bean
@ConditionalOnClass({JSON.class})
Expand All @@ -55,8 +58,11 @@ public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
}

@Bean
public BlobStorageClient blobStorageClient(BlobProperty blobProperty) {
return new BlobStorageClient(blobProperty);
public StorageServiceClientProxy storageServiceClientProxy(ApplicationContext applicationContext) {
StorageServiceClientProxy storageServiceClientProxy = new StorageServiceClientProxy(applicationContext);
storageServiceClientProxy.initCenterStorageClient(storageType);

return storageServiceClientProxy;
}

@Bean
Expand Down
Loading