diff --git a/build.sh b/build.sh index 3cbc2d4a0..7b1b3c308 100755 --- a/build.sh +++ b/build.sh @@ -6,4 +6,5 @@ if [[ -n ${tag} ]]; then versionTag="-t flowci/core:$tag" fi -docker buildx build -f ./core/Dockerfile --platform linux/arm64,linux/amd64 --push -t flowci/core:latest $versionTag ./core \ No newline at end of file +#docker buildx build -f ./core/Dockerfile --platform linux/arm64,linux/amd64 --push -t flowci/core:latest $versionTag ./core +docker build -f ./core/Dockerfile -t flowci/core:latest $versionTag ./core \ No newline at end of file diff --git a/core/Dockerfile b/core/Dockerfile index 0703cd5f3..006418ecc 100644 --- a/core/Dockerfile +++ b/core/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:11-jre-slim +FROM amazoncorretto:11-alpine3.15 ENV WORKER=/flow.ci ENV JAR=flow-ci-core.jar diff --git a/core/src/main/java/com/flowci/core/flow/controller/YmlController.java b/core/src/main/java/com/flowci/core/flow/controller/YmlController.java index dfd533125..ba72ebdc4 100644 --- a/core/src/main/java/com/flowci/core/flow/controller/YmlController.java +++ b/core/src/main/java/com/flowci/core/flow/controller/YmlController.java @@ -17,15 +17,14 @@ package com.flowci.core.flow.controller; import com.flowci.core.auth.annotation.Action; -import com.flowci.core.common.domain.http.RequestMessage; import com.flowci.core.flow.domain.Flow; import com.flowci.core.flow.domain.FlowAction; -import com.flowci.core.flow.domain.Yml; +import com.flowci.core.flow.domain.SimpleYml; +import com.flowci.core.flow.domain.FlowYml; import com.flowci.core.flow.service.FlowService; import com.flowci.core.flow.service.YmlService; import com.flowci.tree.FlowNode; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; +import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -35,40 +34,29 @@ */ @RestController @RequestMapping("/flows") +@AllArgsConstructor public class YmlController { - @Autowired private FlowService flowService; - @Autowired - private YmlService ymlService; + private final YmlService ymlService; @GetMapping("/{flowName}/yml") - public List list(@PathVariable String flowName) { + public FlowYml get(@PathVariable String flowName) { Flow flow = flowService.get(flowName); - return ymlService.list(flow.getId()); + return ymlService.get(flow.getId()); } - @GetMapping("/{flowName}/yml/{ymlName}/obj") - public FlowNode listSteps(@PathVariable String flowName, @PathVariable String ymlName) { + @GetMapping("/{flowName}/yml/steps") + public FlowNode steps(@PathVariable String flowName) { Flow flow = flowService.get(flowName); - return ymlService.getTree(flow.getId(), ymlName).getRoot(); + return ymlService.getTree(flow.getId()).getRoot(); } - @PostMapping("/{flowName}/yml/{ymlName}") + @PostMapping("/{flowName}/yml") @Action(FlowAction.SET_YML) - public void saveYml(@PathVariable String flowName, - @PathVariable String ymlName, - @RequestBody RequestMessage body) { + public void saveYml(@PathVariable String flowName, @RequestBody List body) { Flow flow = flowService.get(flowName); - String yamlInB64 = body.getData(); - ymlService.saveYmlFromB64(flow, ymlName, yamlInB64); - } - - @GetMapping(value = "/{flowName}/yml/{ymlName}", produces = MediaType.APPLICATION_JSON_VALUE) - @Action(FlowAction.GET_YML) - public String getYml(@PathVariable String flowName, @PathVariable String ymlName) { - Flow flow = flowService.get(flowName); - return ymlService.getYmlString(flow.getId(), ymlName); + ymlService.saveYml(flow, body); } } diff --git a/core/src/main/java/com/flowci/core/flow/dao/YmlDao.java b/core/src/main/java/com/flowci/core/flow/dao/FlowYmlDao.java similarity index 73% rename from core/src/main/java/com/flowci/core/flow/dao/YmlDao.java rename to core/src/main/java/com/flowci/core/flow/dao/FlowYmlDao.java index 7b1dc4f4f..2e5386952 100644 --- a/core/src/main/java/com/flowci/core/flow/dao/YmlDao.java +++ b/core/src/main/java/com/flowci/core/flow/dao/FlowYmlDao.java @@ -16,7 +16,7 @@ package com.flowci.core.flow.dao; -import com.flowci.core.flow.domain.Yml; +import com.flowci.core.flow.domain.FlowYml; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; @@ -26,11 +26,9 @@ * @author yang */ @Repository -public interface YmlDao extends YmlCustomDao, MongoRepository { +public interface FlowYmlDao extends MongoRepository { - Optional findByFlowIdAndName(String flowId, String name); + Optional findByFlowId(String flowId); - void deleteAllByFlowId(String flowId); - - void deleteByFlowIdAndName(String flowId, String name); + void deleteByFlowId(String flowId); } diff --git a/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDao.java b/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDao.java deleted file mode 100644 index ac4bfc7ce..000000000 --- a/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDao.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.flowci.core.flow.dao; - -import com.flowci.core.flow.domain.Yml; - -import java.util.List; - -public interface YmlCustomDao { - - /** - * List all Yml instance without raw yaml string - */ - List findAllWithoutRawByFlowId(String flowId); - -} diff --git a/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDaoImpl.java b/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDaoImpl.java deleted file mode 100644 index 5d6ec1881..000000000 --- a/core/src/main/java/com/flowci/core/flow/dao/YmlCustomDaoImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.flowci.core.flow.dao; - -import com.flowci.core.flow.domain.Yml; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoOperations; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import java.util.List; - -import static com.flowci.core.common.domain.Mongoable.SortByCreatedAtASC; - -public class YmlCustomDaoImpl implements YmlCustomDao { - - @Autowired - private MongoOperations operations; - - @Override - public List findAllWithoutRawByFlowId(String flowId) { - Query query = Query.query(Criteria.where("flowId").is(flowId)).with(SortByCreatedAtASC); - query.fields() - .include("id") - .include("name") - .include("flowId") - .include("conditionInB64") - .include("createdBy") - .include("createdAt") - .include("updatedAt") - .include("updatedBy"); - - return operations.find(query, Yml.class); - } -} diff --git a/core/src/main/java/com/flowci/core/flow/domain/CreateOption.java b/core/src/main/java/com/flowci/core/flow/domain/CreateOption.java index 20de7826d..e736e6ebd 100644 --- a/core/src/main/java/com/flowci/core/flow/domain/CreateOption.java +++ b/core/src/main/java/com/flowci/core/flow/domain/CreateOption.java @@ -22,6 +22,8 @@ import lombok.Data; import lombok.experimental.Accessors; +import java.util.Objects; + /** * @author yang */ @@ -29,6 +31,8 @@ @Accessors(chain = true) public class CreateOption { + private static final String TEMPLATE_BLANK = "_blank_"; + private String groupName; @JsonProperty("title") @@ -40,6 +44,10 @@ public class CreateOption { @JsonProperty("yml") private String rawYaml; + public boolean isBlank() { + return Objects.equals(templateTitle, TEMPLATE_BLANK); + } + public boolean hasGroupName() { return StringHelper.hasValue(groupName); } diff --git a/core/src/main/java/com/flowci/core/flow/domain/Yml.java b/core/src/main/java/com/flowci/core/flow/domain/FlowYml.java similarity index 61% rename from core/src/main/java/com/flowci/core/flow/domain/Yml.java rename to core/src/main/java/com/flowci/core/flow/domain/FlowYml.java index 0563a27ae..d78da9e27 100644 --- a/core/src/main/java/com/flowci/core/flow/domain/Yml.java +++ b/core/src/main/java/com/flowci/core/flow/domain/FlowYml.java @@ -18,15 +18,21 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.flowci.core.common.domain.Mongoable; +import com.flowci.util.ObjectsHelper; import com.flowci.util.StringHelper; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.validator.internal.util.CollectionHelper; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; +import java.util.List; +import java.util.Objects; + /** * @author yang */ @@ -34,33 +40,34 @@ @Setter @Document(collection = "flow_yml") @NoArgsConstructor +@AllArgsConstructor @CompoundIndexes( @CompoundIndex( - name = "index_flow_id_and_yaml_name", - def = "{'flowId': 1, 'name': 1}", + name = "index_flow_id_and_yml_name", + def = "{'flowId': 1, 'list.name': 1}", sparse = true, unique = true ) ) -public class Yml extends Mongoable { +public class FlowYml extends Mongoable { - public final static String DEFAULT_NAME = "default"; + public final static String DEFAULT_NAME = ".flowci.yml"; - @Indexed(name = "index_flow_id") + @Indexed(name = "index_yml_flow_id", unique = true) private String flowId; - private String name; - - private String rawInB64; + private List list; - public Yml(String flowId, String name, String rawInB64) { - this.flowId = flowId; - this.name = name; - this.rawInB64 = rawInB64; + public boolean hasYml() { + return ObjectsHelper.hasCollection(list); } - @JsonIgnore - public String getRaw() { - return StringHelper.fromBase64(rawInB64); + public static String[] toRawArray(List list) { + var array = new String[list.size()]; + int i = 0; + for (var item : list) { + array[0] = StringHelper.fromBase64(item.getRawInB64()); + } + return array; } } diff --git a/core/src/main/java/com/flowci/core/flow/domain/SimpleYml.java b/core/src/main/java/com/flowci/core/flow/domain/SimpleYml.java new file mode 100644 index 000000000..614ce89d1 --- /dev/null +++ b/core/src/main/java/com/flowci/core/flow/domain/SimpleYml.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 flow.ci + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.flowci.core.flow.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class SimpleYml { + + private String name; + + private String rawInB64; +} diff --git a/core/src/main/java/com/flowci/core/flow/service/CronServiceImpl.java b/core/src/main/java/com/flowci/core/flow/service/CronServiceImpl.java index 198767d72..97ecc9c63 100644 --- a/core/src/main/java/com/flowci/core/flow/service/CronServiceImpl.java +++ b/core/src/main/java/com/flowci/core/flow/service/CronServiceImpl.java @@ -22,13 +22,11 @@ import com.flowci.core.common.manager.SpringEventManager; import com.flowci.core.common.manager.SpringTaskManager; import com.flowci.core.flow.domain.Flow; -import com.flowci.core.flow.domain.Yml; import com.flowci.core.flow.event.FlowInitEvent; import com.flowci.core.job.domain.Job.Trigger; import com.flowci.core.job.event.CreateNewJobEvent; import com.flowci.exception.NotFoundException; import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.support.CronTrigger; @@ -50,17 +48,20 @@ public class CronServiceImpl implements CronService { private final Map> scheduled = new ConcurrentHashMap<>(); - @Autowired - private TaskScheduler cronScheduler; + private final TaskScheduler cronScheduler; - @Autowired - private SpringEventManager eventManager; + private final SpringEventManager eventManager; - @Autowired - private SpringTaskManager taskManager; + private final SpringTaskManager taskManager; - @Autowired - private YmlService ymlService; + private final YmlService ymlService; + + public CronServiceImpl(TaskScheduler cronScheduler, SpringEventManager eventManager, SpringTaskManager taskManager, YmlService ymlService) { + this.cronScheduler = cronScheduler; + this.eventManager = eventManager; + this.taskManager = taskManager; + this.ymlService = ymlService; + } //==================================================================== // %% Internal events @@ -121,10 +122,9 @@ public void run() { taskManager.run(taskName, false, () -> { try { - Yml yml = ymlService.getYml(flow.getId(), Yml.DEFAULT_NAME); log.info("Start flow '{}' from cron task", flow.getName()); - - eventManager.publish(new CreateNewJobEvent(this, flow, yml.getRaw(), Trigger.SCHEDULER, null)); + var event = new CreateNewJobEvent(this, flow, ymlService.get(flow.getId()), Trigger.SCHEDULER, null); + eventManager.publish(event); } catch (NotFoundException ignore) { // ignore } diff --git a/core/src/main/java/com/flowci/core/flow/service/FlowGroupServiceImpl.java b/core/src/main/java/com/flowci/core/flow/service/FlowGroupServiceImpl.java index 98371398e..da26abf86 100644 --- a/core/src/main/java/com/flowci/core/flow/service/FlowGroupServiceImpl.java +++ b/core/src/main/java/com/flowci/core/flow/service/FlowGroupServiceImpl.java @@ -11,6 +11,7 @@ import com.flowci.exception.DuplicateException; import com.flowci.exception.NotFoundException; import com.google.common.collect.Sets; +import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; @@ -19,6 +20,7 @@ import java.util.Optional; @Service +@AllArgsConstructor public class FlowGroupServiceImpl implements FlowGroupService { private final FlowDao flowDao; @@ -29,17 +31,6 @@ public class FlowGroupServiceImpl implements FlowGroupService { private final SessionManager sessionManager; - @Autowired - public FlowGroupServiceImpl(FlowDao flowDao, - FlowGroupDao flowGroupDao, - FlowUserDao flowUserDao, - SessionManager sessionManager) { - this.flowDao = flowDao; - this.flowGroupDao = flowGroupDao; - this.flowUserDao = flowUserDao; - this.sessionManager = sessionManager; - } - @Override public FlowGroup get(String name) { Optional optional = flowGroupDao.findByName(name); diff --git a/core/src/main/java/com/flowci/core/flow/service/FlowItemServiceImpl.java b/core/src/main/java/com/flowci/core/flow/service/FlowItemServiceImpl.java index c431fec74..b72506fcf 100644 --- a/core/src/main/java/com/flowci/core/flow/service/FlowItemServiceImpl.java +++ b/core/src/main/java/com/flowci/core/flow/service/FlowItemServiceImpl.java @@ -5,11 +5,13 @@ import com.flowci.core.flow.dao.FlowUserDao; import com.flowci.core.flow.domain.FlowItem; import com.google.common.collect.ImmutableList; +import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.util.*; @Service +@AllArgsConstructor public class FlowItemServiceImpl implements FlowItemService { private final FlowItemDao flowItemDao; @@ -18,12 +20,6 @@ public class FlowItemServiceImpl implements FlowItemService { private final SessionManager sessionManager; - public FlowItemServiceImpl(FlowItemDao flowItemDao, FlowUserDao flowUserDao, SessionManager sessionManager) { - this.flowItemDao = flowItemDao; - this.flowUserDao = flowUserDao; - this.sessionManager = sessionManager; - } - @Override public List list() { var email = sessionManager.getUserEmail(); diff --git a/core/src/main/java/com/flowci/core/flow/service/FlowServiceImpl.java b/core/src/main/java/com/flowci/core/flow/service/FlowServiceImpl.java index f8f864e7a..b20a7a6d3 100644 --- a/core/src/main/java/com/flowci/core/flow/service/FlowServiceImpl.java +++ b/core/src/main/java/com/flowci/core/flow/service/FlowServiceImpl.java @@ -34,22 +34,20 @@ import com.flowci.core.job.domain.Job; import com.flowci.core.job.event.CreateNewJobEvent; import com.flowci.core.secret.domain.Secret; -import com.flowci.core.secret.event.CreateAuthEvent; -import com.flowci.core.secret.event.CreateRsaEvent; import com.flowci.core.secret.event.GetSecretEvent; import com.flowci.core.user.event.UserDeletedEvent; -import com.flowci.domain.*; +import com.flowci.domain.StringVars; +import com.flowci.domain.VarType; +import com.flowci.domain.VarValue; import com.flowci.exception.ArgumentException; import com.flowci.exception.DuplicateException; import com.flowci.exception.NotFoundException; import com.flowci.exception.StatusException; import com.flowci.store.FileManager; -import com.flowci.util.ObjectsHelper; import com.flowci.util.StringHelper; import com.google.common.collect.Sets; +import lombok.AllArgsConstructor; import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.dao.DuplicateKeyException; @@ -63,41 +61,30 @@ */ @Log4j2 @Service +@AllArgsConstructor public class FlowServiceImpl implements FlowService { - @Autowired - private FlowDao flowDao; + private final FlowDao flowDao; - @Autowired - private FlowGroupDao flowGroupDao; + private final FlowGroupDao flowGroupDao; - @Autowired - private FlowUserDao flowUserDao; + private final FlowUserDao flowUserDao; - @Autowired - private SessionManager sessionManager; + private final SessionManager sessionManager; - @Autowired - private SpringEventManager eventManager; + private final SpringEventManager eventManager; - @Qualifier("fileManager") - @Autowired - private FileManager fileManager; + private final FileManager fileManager; - @Autowired - private HttpRequestManager httpRequestManager; + private final HttpRequestManager httpRequestManager; - @Autowired - private YmlService ymlService; + private final YmlService ymlService; - @Autowired - private CronService cronService; + private final CronService cronService; - @Autowired - private List