Java tutorial
/* AiAi, Copyright (C) 2017 - 2018, Serge Maslyukov This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ package aiai.ai.station; import aiai.ai.Consts; import aiai.ai.Enums; import aiai.ai.Globals; import aiai.ai.comm.Command; import aiai.ai.comm.Protocol; import aiai.ai.station.actors.UploadResourceActor; import aiai.ai.station.tasks.UploadResourceTask; import aiai.ai.yaml.env.EnvYaml; import aiai.ai.yaml.env.EnvYamlUtils; import aiai.ai.yaml.station.StationTask; import aiai.ai.yaml.metadata.Metadata; import aiai.ai.yaml.metadata.MetadataUtils; import aiai.ai.yaml.task.TaskParamYaml; import aiai.ai.yaml.task.TaskParamYamlUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.Charsets; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @Service @Slf4j public class StationService { private final Globals globals; private final StationTaskService stationTaskService; private final TaskParamYamlUtils taskParamYamlUtils; private final UploadResourceActor uploadResourceActor; private String env; private EnvYaml envYaml; private Metadata metadata = new Metadata(); public StationService(Globals globals, StationTaskService stationTaskService, TaskParamYamlUtils taskParamYamlUtils, UploadResourceActor uploadResourceActor) { this.globals = globals; this.stationTaskService = stationTaskService; this.taskParamYamlUtils = taskParamYamlUtils; this.uploadResourceActor = uploadResourceActor; } @PostConstruct public void init() { if (!globals.isStationEnabled) { return; } final File file = new File(globals.stationDir, Consts.ENV_YAML_FILE_NAME); if (!file.exists()) { log.warn("Station's environment config file doesn't exist: {}", file.getPath()); return; } try { env = FileUtils.readFileToString(file, Charsets.UTF_8); envYaml = EnvYamlUtils.toEnvYaml(env); if (envYaml == null) { log.error("env.yaml wasn't found or empty. path: {}{}env.yaml", globals.stationDir, File.separatorChar); throw new IllegalStateException("Station isn't configured, env.yaml is empty or doesn't exist"); } } catch (IOException e) { log.error("Error", e); throw new IllegalStateException("Error while loading file: " + file.getPath(), e); } final File metadataFile = new File(globals.stationDir, Consts.METADATA_YAML_FILE_NAME); if (!metadataFile.exists()) { log.warn("Station's metadata file doesn't exist: {}", file.getPath()); return; } try (FileInputStream fis = new FileInputStream(metadataFile)) { metadata = MetadataUtils.to(fis); } catch (IOException e) { log.error("Error", e); throw new IllegalStateException("Error while loading file: " + metadataFile.getPath(), e); } //noinspection unused int i = 0; } public String getEnv() { return env; } EnvYaml getEnvYaml() { return envYaml; } Command produceReportStationStatus() { //noinspection UnnecessaryLocalVariable Protocol.ReportStationStatus reportStationStatus = new Protocol.ReportStationStatus(getEnv(), globals.stationActiveTime); return reportStationStatus; } private static final Object syncObj = new Object(); public String getStationId() { synchronized (syncObj) { return metadata.metadata.get(StationConsts.STATION_ID); } } public void setStationId(String stationId) { if (StringUtils.isBlank(stationId)) { throw new IllegalStateException("StationId is null"); } synchronized (syncObj) { metadata.metadata.put(StationConsts.STATION_ID, stationId); updateMetadataFile(); } } private void updateMetadataFile() { final File metadataFile = new File(globals.stationDir, Consts.METADATA_YAML_FILE_NAME); if (metadataFile.exists()) { log.info("Metadata file exists. Make backup"); File yamlFileBak = new File(globals.stationDir, Consts.METADATA_YAML_FILE_NAME + ".bak"); //noinspection ResultOfMethodCallIgnored yamlFileBak.delete(); if (metadataFile.exists()) { //noinspection ResultOfMethodCallIgnored metadataFile.renameTo(yamlFileBak); } } try { FileUtils.write(metadataFile, MetadataUtils.toString(metadata), Charsets.UTF_8, false); } catch (IOException e) { log.error("Error", e); throw new IllegalStateException("Error while writing to file: " + metadataFile.getPath(), e); } } public void markAsDelivered(List<Long> ids) { List<StationTask> list = new ArrayList<>(); for (Long id : ids) { StationTask seq = stationTaskService.findByTaskId(id); if (seq == null) { continue; } seq.setDelivered(true); list.add(seq); } stationTaskService.saveAll(list); } public void assignTasks(List<Protocol.AssignedTask.Task> tasks) { if (tasks == null || tasks.isEmpty()) { return; } synchronized (StationSyncHolder.stationGlobalSync) { for (Protocol.AssignedTask.Task task : tasks) { stationTaskService.createTask(task.taskId, task.flowInstanceId, task.params); } } } public Enums.ResendTaskOutputResourceStatus resendTaskOutputResource(long taskId) { File taskDir = stationTaskService.prepareTaskDir(taskId); File paramFile = new File(taskDir, Consts.ARTIFACTS_DIR + File.separatorChar + Consts.PARAMS_YAML); if (!paramFile.isFile() || !paramFile.exists()) { return Enums.ResendTaskOutputResourceStatus.TASK_IS_BROKEN; } String params; try { params = FileUtils.readFileToString(paramFile, StandardCharsets.UTF_8); } catch (IOException e) { log.error("Error reading param file " + paramFile.getPath(), e); return Enums.ResendTaskOutputResourceStatus.TASK_PARAM_FILE_NOT_FOUND; } final TaskParamYaml taskParamYaml = taskParamYamlUtils.toTaskYaml(params); boolean isResourcesOk = true; final AssetFile assetFile = StationResourceUtils.prepareResourceFile(taskDir, Enums.BinaryDataType.DATA, taskParamYaml.outputResourceCode, taskParamYaml.outputResourceCode); // is this resource prepared? if (assetFile.isError || !assetFile.isContent) { log.info("Resource hasn't been prepared yet, {}", assetFile); return Enums.ResendTaskOutputResourceStatus.RESOURCE_NOT_FOUND; } uploadResourceActor.add(new UploadResourceTask(assetFile.file, taskId)); return Enums.ResendTaskOutputResourceStatus.SEND_SCHEDULED; } }