diff --git a/core/archiver/build.gradle b/core/archiver/build.gradle new file mode 100644 index 000000000..cf260aa83 --- /dev/null +++ b/core/archiver/build.gradle @@ -0,0 +1,6 @@ +dependencies { + compile project(':core:base') + compile "net.lingala.zip4j:zip4j:2.5.0" + + testCompile project(":core:base").sourceSets.test.output +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/AbstractAsyncArchiver.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/AbstractAsyncArchiver.java new file mode 100644 index 000000000..4d8ec10e4 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/AbstractAsyncArchiver.java @@ -0,0 +1,75 @@ +package com.nubeiot.core.archiver; + +import java.io.File; +import java.nio.file.Path; + +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +import com.nubeiot.core.event.EventbusClient; + +import lombok.Getter; +import lombok.NonNull; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.progress.ProgressMonitor; +import net.lingala.zip4j.progress.ProgressMonitor.Result; +import net.lingala.zip4j.progress.ProgressMonitor.State; + +@Getter +@Accessors(fluent = true) +@SuperBuilder +public abstract class AbstractAsyncArchiver implements AsyncArchiver { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @NonNull + private final EventbusClient transporter; + @NonNull + private final String notifiedAddress; + + protected void execute(@NonNull ZipArgument argument, @NonNull File destFolder, @NonNull File originFile) { + try { + final ZipFile zipFile = createZipFile(argument, destFolder, originFile); + zipFile.setRunInThread(true); + run(argument, zipFile, destFolder, originFile); + transporter().getVertx() + .setPeriodic(argument.watcherDelayInMilli(), id -> watch(id, argument, zipFile, originFile)); + } catch (ZipException e) { + onError(argument, new IllegalArgumentException(e)); + } + } + + protected abstract ZipFile createZipFile(@NonNull ZipArgument argument, @NonNull File destination, + @NonNull File originFile); + + protected abstract void run(@NonNull ZipArgument argument, @NonNull ZipFile zipFile, @NonNull File destination, + @NonNull File originFile) throws ZipException; + + protected void watch(long timerId, @NonNull ZipArgument argument, @NonNull ZipFile zipFile, + @NonNull File originFile) { + final ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); + final Path path = zipFile.getFile().toPath(); + if (progressMonitor.getState().equals(State.BUSY)) { + logger.debug("{} {} | Progress: {}% | Current file: {} | Current task: {}", action(), path, + progressMonitor.getPercentDone(), progressMonitor.getFileName(), + progressMonitor.getCurrentTask()); + return; + } + transporter().getVertx().cancelTimer(timerId); + final Result result = progressMonitor.getResult(); + if (result == Result.SUCCESS) { + onSuccess(createOutput(argument, zipFile, progressMonitor, originFile)); + return; + } + onError(argument, new IllegalArgumentException(progressMonitor.getException())); + } + + protected abstract String action(); + + protected abstract ZipOutput createOutput(@NonNull ZipArgument argument, @NonNull ZipFile zipFile, + @NonNull ProgressMonitor progressMonitor, @NonNull File originFile); + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncArchiver.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncArchiver.java new file mode 100644 index 000000000..8181a06c9 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncArchiver.java @@ -0,0 +1,77 @@ +package com.nubeiot.core.archiver; + +import java.nio.file.Path; + +import com.nubeiot.core.component.EventClientProxy; +import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventMessage; + +import lombok.NonNull; + +/** + * Represents Async archvier. + * + * @since 1.0.0 + */ +public interface AsyncArchiver extends EventClientProxy { + + /** + * The constant EXT_ZIP_FILE. + */ + String EXT_ZIP_FILE = ".zip"; + + /** + * Appends {@code ext} in file name. + * + * @param fileName the file name + * @return the string + * @since 1.0.0 + */ + @NonNull + static String ext(@NonNull String fileName) { + return fileName + EXT_ZIP_FILE; + } + + /** + * Appends {@code ext} in file name. + * + * @param fileName the file name + * @return the string + * @since 1.0.0 + */ + @NonNull + static String ext(@NonNull Path fileName) { + return ext(fileName.toString()); + } + + /** + * Notified address string. + * + * @return the string + * @since 1.0.0 + */ + @NonNull String notifiedAddress(); + + /** + * On success. + * + * @param information the information + * @since 1.0.0 + */ + default void onSuccess(@NonNull ZipOutput information) { + transporter().publish(notifiedAddress(), EventMessage.success(EventAction.NOTIFY, information.toJson())); + } + + /** + * On error. + * + * @param argument the argument + * @param throwable the throwable + * @since 1.0.0 + */ + default void onError(@NonNull ZipArgument argument, @NonNull Throwable throwable) { + transporter().publish(notifiedAddress(), + EventMessage.error(EventAction.NOTIFY_ERROR, throwable, argument.trackingInfo())); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncUnzip.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncUnzip.java new file mode 100644 index 000000000..dc49d5bf4 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncUnzip.java @@ -0,0 +1,31 @@ +package com.nubeiot.core.archiver; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.nubeiot.core.utils.FileUtils; +import com.nubeiot.core.utils.Strings; + +import lombok.NonNull; + +public interface AsyncUnzip extends AsyncArchiver { + + default void extract(@NonNull ZipArgument argument, @NonNull String destFolder, @NonNull String zipFile) { + extract(argument, Paths.get(destFolder), Paths.get(zipFile)); + } + + default void extract(@NonNull ZipArgument argument, @NonNull Path destFolder, @NonNull Path zipFile) { + extract(argument, destFolder.toFile(), zipFile.toFile()); + } + + void extract(@NonNull ZipArgument argument, @NonNull File destFolder, @NonNull File zipFile); + + default String computeExtractedFolder(@NonNull ZipArgument argument, @NonNull File zippedFile) { + if (Strings.isNotBlank(argument.overriddenDestFileName())) { + return argument.overriddenDestFileName(); + } + return FileUtils.withoutExtension(zippedFile.toPath().getFileName().toString()); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZip.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZip.java new file mode 100644 index 000000000..18539bd67 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZip.java @@ -0,0 +1,64 @@ +package com.nubeiot.core.archiver; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.nubeiot.core.utils.DateTimes; +import com.nubeiot.core.utils.Strings; + +import lombok.NonNull; + +/** + * Represents Async zip. + * + * @since 1.0.0 + */ +public interface AsyncZip extends AsyncArchiver { + + /** + * Do zip folder. + * + * @param argument the argument + * @param destFolder the dest folder + * @param tobeZipped the tobe zipped + * @see ZipArgument + * @since 1.0.0 + */ + default void zip(@NonNull ZipArgument argument, @NonNull String destFolder, @NonNull String tobeZipped) { + zip(argument, Paths.get(destFolder), Paths.get(tobeZipped)); + } + + /** + * Do zip folder. + * + * @param argument the argument + * @param destFolder the dest folder + * @param tobeZipped the tobe zipped + * @see ZipArgument + * @since 1.0.0 + */ + default void zip(@NonNull ZipArgument argument, @NonNull Path destFolder, @NonNull Path tobeZipped) { + zip(argument, destFolder.toFile(), tobeZipped.toFile()); + } + + /** + * Do zip folder. + * + * @param argument the argument + * @param destFolder the dest folder + * @param tobeZipped the tobe zipped + * @see ZipArgument + * @since 1.0.0 + */ + void zip(@NonNull ZipArgument argument, @NonNull File destFolder, @NonNull File tobeZipped); + + default String computeZipName(@NonNull ZipArgument argument, @NonNull File toZippedFile) { + if (Strings.isNotBlank(argument.overriddenDestFileName())) { + return AsyncArchiver.ext(argument.overriddenDestFileName()); + } + final String fileName = toZippedFile.toPath().getFileName().toString(); + return AsyncArchiver.ext(fileName + (argument.appendTimestamp() ? "-" + DateTimes.nowMilli() : "")); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZipFolder.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZipFolder.java new file mode 100644 index 000000000..e2c3252da --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/AsyncZipFolder.java @@ -0,0 +1,51 @@ +package com.nubeiot.core.archiver; + +import java.io.File; + +import com.nubeiot.core.utils.ExecutorHelpers; + +import lombok.NonNull; +import lombok.experimental.SuperBuilder; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.progress.ProgressMonitor; + +@SuperBuilder +public final class AsyncZipFolder extends AbstractAsyncArchiver implements AsyncZip { + + @Override + public void zip(@NonNull ZipArgument argument, @NonNull File destFolder, @NonNull File tobeZipped) { + ExecutorHelpers.blocking(transporter().getVertx(), () -> execute(argument, destFolder, tobeZipped)); + } + + @Override + protected ZipFile createZipFile(@NonNull ZipArgument argument, @NonNull File destination, + @NonNull File originFile) { + return new ZipFile(destination.toPath().resolve(computeZipName(argument, originFile)).toString(), + argument.toPassword()); + } + + @Override + protected void run(@NonNull ZipArgument argument, ZipFile zipFile, @NonNull File destination, + @NonNull File originFile) throws ZipException { + zipFile.addFolder(originFile, argument.zipParameters()); + } + + @Override + protected String action() { + return "Compressing"; + } + + @Override + protected ZipOutput createOutput(@NonNull ZipArgument argument, @NonNull ZipFile zipFile, + @NonNull ProgressMonitor progressMonitor, @NonNull File originFile) { + return ZipOutput.builder() + .inputPath(originFile.getPath()) + .outputPath(zipFile.getFile().toString()) + .size(zipFile.getFile().length()) + .lastModified(zipFile.getFile().lastModified()) + .trackingInfo(argument.trackingInfo()) + .build(); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/DefaultAsyncUnzip.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/DefaultAsyncUnzip.java new file mode 100644 index 000000000..a3e9c30a1 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/DefaultAsyncUnzip.java @@ -0,0 +1,51 @@ +package com.nubeiot.core.archiver; + +import java.io.File; +import java.nio.file.Paths; + +import com.nubeiot.core.utils.ExecutorHelpers; + +import lombok.NonNull; +import lombok.experimental.SuperBuilder; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.progress.ProgressMonitor; + +@SuperBuilder +public final class DefaultAsyncUnzip extends AbstractAsyncArchiver implements AsyncUnzip { + + @Override + public void extract(@NonNull ZipArgument argument, @NonNull File destFolder, @NonNull File zipFile) { + ExecutorHelpers.blocking(transporter().getVertx(), () -> execute(argument, destFolder, zipFile)); + } + + @Override + protected ZipFile createZipFile(@NonNull ZipArgument argument, @NonNull File destination, + @NonNull File originFile) { + return new ZipFile(originFile, argument.toPassword()); + } + + @Override + protected void run(@NonNull ZipArgument argument, @NonNull ZipFile zipFile, @NonNull File destination, + @NonNull File originFile) throws ZipException { + zipFile.extractAll(destination.toPath().resolve(computeExtractedFolder(argument, originFile)).toString()); + } + + @Override + protected String action() { + return "Extracting"; + } + + @Override + protected ZipOutput createOutput(@NonNull ZipArgument argument, @NonNull ZipFile zipFile, + @NonNull ProgressMonitor progressMonitor, @NonNull File originFile) { + final File outputFile = Paths.get(progressMonitor.getFileName()).getParent().toFile(); + return ZipOutput.builder() + .inputPath(originFile.getPath()) + .outputPath(outputFile.getPath()) + .lastModified(outputFile.lastModified()) + .trackingInfo(argument.trackingInfo()) + .build(); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipArgument.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipArgument.java new file mode 100644 index 000000000..e71cdb6f1 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipArgument.java @@ -0,0 +1,57 @@ +package com.nubeiot.core.archiver; + +import io.vertx.core.json.JsonObject; + +import com.nubeiot.core.dto.JsonData; +import com.nubeiot.core.utils.Strings; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.experimental.Accessors; +import net.lingala.zip4j.model.ZipParameters; + +@Getter +@Accessors(fluent = true) +@Builder(builderClassName = "Builder") +public final class ZipArgument implements JsonData { + + private final JsonObject trackingInfo; + private final boolean appendTimestamp; + private final String overriddenDestFileName; + private final String password; + private final long watcherDelayInMilli; + @NonNull + private final ZipParameters zipParameters; + + public static ZipArgument createDefault(JsonObject trackingInfo) { + return ZipArgument.builder() + .trackingInfo(trackingInfo) + .appendTimestamp(true) + .watcherDelayInMilli(100) + .zipParameters(defaultZipParameters()) + .build(); + } + + public static ZipArgument noTimestamp() { + return noTimestamp(null); + } + + public static ZipArgument noTimestamp(JsonObject trackingInfo) { + return ZipArgument.builder() + .trackingInfo(trackingInfo) + .appendTimestamp(false) + .watcherDelayInMilli(100).zipParameters(defaultZipParameters()).build(); + } + + static @NonNull ZipParameters defaultZipParameters() { + ZipParameters parameters = new ZipParameters(); + parameters.setIncludeRootFolder(false); + return parameters; + } + + public char[] toPassword() { + return Strings.isBlank(password) ? null : password.toCharArray(); + } + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipNotificationHandler.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipNotificationHandler.java new file mode 100644 index 000000000..9bb99b565 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipNotificationHandler.java @@ -0,0 +1,45 @@ +package com.nubeiot.core.archiver; + +import java.util.Arrays; +import java.util.Collection; + +import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventContractor; +import com.nubeiot.core.event.EventListener; +import com.nubeiot.core.exceptions.ErrorData; + +import lombok.NonNull; + +/** + * Represents Zip notification handler. + * + * @since 1.0.0 + */ +public interface ZipNotificationHandler extends EventListener { + + @Override + default @NonNull Collection getAvailableEvents() { + return Arrays.asList(EventAction.NOTIFY, EventAction.NOTIFY_ERROR); + } + + /** + * Handles {@code success}. + * + * @param result the result + * @return the boolean + * @since 1.0.0 + */ + @EventContractor(action = EventAction.NOTIFY, returnType = boolean.class) + boolean success(@NonNull ZipOutput result); + + /** + * Handles {@code error} case. + * + * @param error the error + * @return the boolean + * @since 1.0.0 + */ + @EventContractor(action = EventAction.NOTIFY_ERROR, returnType = boolean.class) + boolean error(@NonNull ErrorData error); + +} diff --git a/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipOutput.java b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipOutput.java new file mode 100644 index 000000000..92aa48778 --- /dev/null +++ b/core/archiver/src/main/java/com/nubeiot/core/archiver/ZipOutput.java @@ -0,0 +1,44 @@ +package com.nubeiot.core.archiver; + +import java.time.OffsetDateTime; + +import io.vertx.core.json.JsonObject; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.nubeiot.core.dto.JsonData; +import com.nubeiot.core.utils.DateTimes; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder(builderClassName = "Builder") +@JsonDeserialize(builder = ZipOutput.Builder.class) +public final class ZipOutput implements JsonData { + + private final JsonObject trackingInfo; + private final String inputPath; + private final String outputPath; + private final long size; + private final OffsetDateTime lastModified; + + + @JsonPOJOBuilder(withPrefix = "") + public static class Builder { + + public Builder lastModified(long lastModified) { + this.lastModified = DateTimes.from(lastModified); + return this; + } + + @JsonProperty("lastModified") + public Builder lastModified(OffsetDateTime lastModified) { + this.lastModified = lastModified; + return this; + } + + } + +} diff --git a/core/archiver/src/test/java/com/nubeiot/core/archiver/AsyncZipFolderTest.java b/core/archiver/src/test/java/com/nubeiot/core/archiver/AsyncZipFolderTest.java new file mode 100644 index 000000000..652085bd2 --- /dev/null +++ b/core/archiver/src/test/java/com/nubeiot/core/archiver/AsyncZipFolderTest.java @@ -0,0 +1,111 @@ +package com.nubeiot.core.archiver; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; + +import io.vertx.core.Vertx; +import io.vertx.core.eventbus.DeliveryOptions; +import io.vertx.core.json.JsonObject; +import io.vertx.ext.unit.Async; +import io.vertx.ext.unit.TestContext; +import io.vertx.ext.unit.junit.VertxUnitRunner; + +import com.nubeiot.core.TestHelper; +import com.nubeiot.core.component.EventClientProxy; +import com.nubeiot.core.event.EventbusClient; +import com.nubeiot.core.exceptions.NubeException.ErrorCode; +import com.nubeiot.core.utils.FileUtils; + +@RunWith(VertxUnitRunner.class) +public class AsyncZipFolderTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + private EventbusClient client; + private File origin; + private File dest; + + @Before + public void setup() throws IOException { + final Vertx vertx = Vertx.vertx(); + client = EventClientProxy.create(vertx, new DeliveryOptions()).transporter(); + origin = folder.newFolder("origin"); + dest = folder.newFolder("dest"); + } + + @Test + public void test_zip(TestContext context) throws IOException { + folder.newFile(folder.getRoot().toPath().relativize(origin.toPath().resolve("abc.txt")).toString()); + folder.newFile(folder.getRoot().toPath().relativize(origin.toPath().resolve("def.txt")).toString()); + final Path xyz = origin.toPath().resolve("xyz"); + assert xyz.toFile().mkdirs(); + folder.newFile(folder.getRoot().toPath().relativize(xyz.resolve("ghj.txt")).toString()); + final String outFile = AsyncArchiver.ext(dest.toPath().resolve(origin.toPath().getFileName())); + final ZipOutput expected = ZipOutput.builder() + .inputPath(origin.toString()) + .outputPath(outFile) + .size(384) + .build(); + createNotifier(context, expected.toJson(), context.async(), null); + AsyncZipFolder.builder() + .transporter(client) + .notifiedAddress("xxx") + .build() + .zip(ZipArgument.noTimestamp(), dest, origin); + } + + @Test + public void test_unzip(TestContext context) throws InterruptedException { + final File zipFile = FileUtils.getClasspathFile("origin.zip").toFile(); + final ZipOutput expected = ZipOutput.builder() + .inputPath(zipFile.toString()) + .outputPath(dest.toPath().resolve("origin").toString()) + .build(); + final Async async = context.async(2); + final CountDownLatch latch = new CountDownLatch(1); + createNotifier(context, expected.toJson(), async, latch); + DefaultAsyncUnzip.builder() + .transporter(client) + .notifiedAddress("xxx") + .build() + .extract(ZipArgument.noTimestamp(), dest, zipFile); + latch.await(TestHelper.TEST_TIMEOUT_SEC, TimeUnit.SECONDS); + final Path extractFile = dest.toPath().resolve("origin").resolve("abc.txt"); + client.getVertx().fileSystem().exists(extractFile.toString(), event -> { + context.assertTrue(event.succeeded()); + context.assertTrue(event.result()); + TestHelper.testComplete(async); + }); + } + + @Test + public void test_unzip_not_found(TestContext context) { + final Async async = context.async(); + final Path zipFile = dest.toPath().resolve("origin.zip"); + final JsonObject expected = new JsonObject().put("code", ErrorCode.INVALID_ARGUMENT) + .put("message", "java.io.FileNotFoundException: " + zipFile + + " (The system cannot find the file " + + "specified)"); + createNotifier(context, expected, async, null); + DefaultAsyncUnzip.builder() + .transporter(client) + .notifiedAddress("xxx") + .build() + .extract(ZipArgument.noTimestamp(), dest.toPath(), zipFile); + } + + private void createNotifier(TestContext context, JsonObject expected, Async async, CountDownLatch latch) { + final TestZipNotifier notifier = new TestZipNotifier(context, async, expected, latch); + client.register("xxx", notifier); + } + +} diff --git a/core/archiver/src/test/java/com/nubeiot/core/archiver/TestZipNotifier.java b/core/archiver/src/test/java/com/nubeiot/core/archiver/TestZipNotifier.java new file mode 100644 index 000000000..4ffbc0c1b --- /dev/null +++ b/core/archiver/src/test/java/com/nubeiot/core/archiver/TestZipNotifier.java @@ -0,0 +1,53 @@ +package com.nubeiot.core.archiver; + +import java.util.Optional; +import java.util.concurrent.CountDownLatch; + +import io.vertx.core.json.JsonObject; +import io.vertx.ext.unit.Async; +import io.vertx.ext.unit.TestContext; + +import com.nubeiot.core.TestHelper.JsonHelper; +import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventContractor; +import com.nubeiot.core.exceptions.ErrorData; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public final class TestZipNotifier implements ZipNotificationHandler { + + @NonNull + private final TestContext testContext; + @NonNull + private final Async async; + @NonNull + private final JsonObject expected; + private final CountDownLatch latch; + + @Override + @EventContractor(action = EventAction.NOTIFY, returnType = boolean.class) + public boolean success(@NonNull ZipOutput response) { + try { + System.out.println(response.toJson()); + JsonHelper.assertJson(testContext, async, expected, response.toJson(), JsonHelper.ignore("lastModified")); + } finally { + Optional.ofNullable(latch).ifPresent(CountDownLatch::countDown); + } + return true; + } + + @Override + @EventContractor(action = EventAction.NOTIFY_ERROR, returnType = boolean.class) + public boolean error(@NonNull ErrorData error) { + try { + System.out.println(error.toJson()); + JsonHelper.assertJson(testContext, async, expected, error.getError().toJson()); + } finally { + Optional.ofNullable(latch).ifPresent(CountDownLatch::countDown); + } + return true; + } + +} diff --git a/core/base/src/main/java/com/nubeiot/core/dto/RequestFilter.java b/core/base/src/main/java/com/nubeiot/core/dto/RequestFilter.java index 7df95d442..2c6072507 100644 --- a/core/base/src/main/java/com/nubeiot/core/dto/RequestFilter.java +++ b/core/base/src/main/java/com/nubeiot/core/dto/RequestFilter.java @@ -10,6 +10,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; +import lombok.NonNull; /** * Represents for Request filter. @@ -80,8 +81,8 @@ public Set getIncludes() { return Arrays.stream(getString(RequestFilter.Filters.INCLUDE, "").split(",")).collect(Collectors.toSet()); } - private boolean parseBoolean(String pretty) { - return Boolean.parseBoolean(Strings.toString(this.getValue(pretty))); + public boolean parseBoolean(@NonNull String param) { + return Boolean.parseBoolean(Strings.toString(this.getValue(param))); } /** diff --git a/core/base/src/main/java/com/nubeiot/core/event/AnnotationHandler.java b/core/base/src/main/java/com/nubeiot/core/event/AnnotationHandler.java index 84e43d72a..3359d73af 100644 --- a/core/base/src/main/java/com/nubeiot/core/event/AnnotationHandler.java +++ b/core/base/src/main/java/com/nubeiot/core/event/AnnotationHandler.java @@ -137,7 +137,9 @@ private Object[] parseMessage(EventMessage message, Map> params if (params.isEmpty()) { return new Object[] {}; } - JsonObject data = message.isError() ? message.getError().toJson() : message.getData(); + JsonObject data = message.isError() && Objects.nonNull(message.getError()) + ? message.getError().toJson() + : message.getData(); if (Objects.isNull(data)) { throw new NubeException(ErrorCode.INVALID_ARGUMENT, Strings.format("Event Message Data is null: {0}", message.toJson())); diff --git a/core/base/src/main/java/com/nubeiot/core/event/EventAction.java b/core/base/src/main/java/com/nubeiot/core/event/EventAction.java index a6366be0e..173a22603 100644 --- a/core/base/src/main/java/com/nubeiot/core/event/EventAction.java +++ b/core/base/src/main/java/com/nubeiot/core/event/EventAction.java @@ -22,6 +22,7 @@ public enum EventAction implements Serializable { GET_ONE, GET_LIST, CREATE_OR_UPDATE, + BACKUP, RETURN, MIGRATE, UNKNOWN, diff --git a/core/base/src/main/java/com/nubeiot/core/event/EventMessage.java b/core/base/src/main/java/com/nubeiot/core/event/EventMessage.java index 2d89d3eaa..78926ef73 100644 --- a/core/base/src/main/java/com/nubeiot/core/event/EventMessage.java +++ b/core/base/src/main/java/com/nubeiot/core/event/EventMessage.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.nubeiot.core.dto.JsonData; import com.nubeiot.core.enums.Status; +import com.nubeiot.core.exceptions.ErrorData; import com.nubeiot.core.exceptions.ErrorMessage; import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.exceptions.NubeException.ErrorCode; @@ -85,10 +86,19 @@ private EventMessage(Status status, EventAction action, EventAction prevAction, this(status, action, prevAction, Objects.isNull(data) ? null : data.getMap(), null, null); } - public static EventMessage error(EventAction action, @NonNull Throwable throwable) { + public static EventMessage error(@NonNull EventAction action, @NonNull Throwable throwable) { return new EventMessage(Status.FAILED, action, ErrorMessage.parse(throwable)); } + public static EventMessage error(@NonNull EventAction action, @NonNull Throwable throwable, JsonObject extra) { + return new EventMessage(Status.FAILED, action, + ErrorData.builder().throwable(throwable).extraInfo(extra).build()); + } + + public static EventMessage error(@NonNull EventAction action, @NonNull ErrorData errorData) { + return new EventMessage(Status.FAILED, action, errorData); + } + public static EventMessage error(@NonNull EventAction action, @NonNull ErrorCode code, @NonNull String message) { return new EventMessage(Status.FAILED, action, ErrorMessage.parse(code, message)); } diff --git a/core/base/src/main/java/com/nubeiot/core/exceptions/ErrorData.java b/core/base/src/main/java/com/nubeiot/core/exceptions/ErrorData.java index 96db82fe2..4f62b8571 100644 --- a/core/base/src/main/java/com/nubeiot/core/exceptions/ErrorData.java +++ b/core/base/src/main/java/com/nubeiot/core/exceptions/ErrorData.java @@ -17,7 +17,7 @@ @Getter @Builder(builderClassName = "Builder") @JsonDeserialize(builder = ErrorData.Builder.class) -public class ErrorData implements JsonData { +public final class ErrorData implements JsonData { @NonNull private final ErrorMessage error; diff --git a/core/base/src/main/java/com/nubeiot/core/utils/DateTimes.java b/core/base/src/main/java/com/nubeiot/core/utils/DateTimes.java index 0654c6d9d..aa73f43e6 100644 --- a/core/base/src/main/java/com/nubeiot/core/utils/DateTimes.java +++ b/core/base/src/main/java/com/nubeiot/core/utils/DateTimes.java @@ -30,6 +30,53 @@ public final class DateTimes { private static final Logger logger = LoggerFactory.getLogger(DateTimes.class); + public static LocalDateTime nowUTC() { + return fromUTC(Instant.now()); + } + + public static LocalDateTime fromUTC(@NonNull Instant instant) { + return LocalDateTime.ofInstant(instant, ZoneOffset.UTC); + } + + public static ZonedDateTime toUTC(@NonNull Date date) { + return DateTimes.toUTC(date.toInstant()); + } + + public static ZonedDateTime toUTC(@NonNull Instant date) { + return DateTimes.toUTC(date.atZone(ZoneId.systemDefault())); + } + + public static ZonedDateTime toUTC(@NonNull LocalDateTime time) { + return DateTimes.toUTC(time, ZoneId.systemDefault()); + } + + public static ZonedDateTime toUTC(@NonNull LocalDateTime time, @NonNull ZoneId zoneId) { + return DateTimes.toUTC(time.atZone(zoneId)); + } + + public static ZonedDateTime toUTC(@NonNull ZonedDateTime dateTime) { + return DateTimes.toZone(dateTime, ZoneOffset.UTC); + } + + public static ZonedDateTime toZone(@NonNull ZonedDateTime dateTime, @NonNull ZoneId toZone) { + return dateTime.withZoneSameInstant(toZone); + } + + public static OffsetDateTime now() { + return from(Instant.now()); + } + + public static long nowMilli() { + return Instant.now().toEpochMilli(); + } + + public static OffsetDateTime from(@NonNull Instant instant) { + return OffsetDateTime.ofInstant(instant, ZoneOffset.UTC); + } + + public static OffsetDateTime from(long milliseconds) { + return from(Instant.ofEpochMilli(milliseconds)); + } /** * Utilities class for parsing {@code date/time/datetime} in {@code iso8601} to appropriate {@code java data type} @@ -110,48 +157,4 @@ public static JsonObject format(@NonNull Date date, TimeZone timeZone) { } - public static LocalDateTime nowUTC() { - return fromUTC(Instant.now()); - } - - public static LocalDateTime fromUTC(@NonNull Instant instant) { - return LocalDateTime.ofInstant(instant, ZoneOffset.UTC); - } - - public static ZonedDateTime toUTC(@NonNull Date date) { - return DateTimes.toUTC(date.toInstant()); - } - - public static ZonedDateTime toUTC(@NonNull Instant date) { - return DateTimes.toUTC(date.atZone(ZoneId.systemDefault())); - } - - public static ZonedDateTime toUTC(@NonNull LocalDateTime time) { - return DateTimes.toUTC(time, ZoneId.systemDefault()); - } - - public static ZonedDateTime toUTC(@NonNull LocalDateTime time, @NonNull ZoneId zoneId) { - return DateTimes.toUTC(time.atZone(zoneId)); - } - - public static ZonedDateTime toUTC(@NonNull ZonedDateTime dateTime) { - return DateTimes.toZone(dateTime, ZoneOffset.UTC); - } - - public static ZonedDateTime toZone(@NonNull ZonedDateTime dateTime, @NonNull ZoneId toZone) { - return dateTime.withZoneSameInstant(toZone); - } - - public static OffsetDateTime now() { - return from(Instant.now()); - } - - public static long nowMilli() { - return Instant.now().toEpochMilli(); - } - - public static OffsetDateTime from(@NonNull Instant instant) { - return OffsetDateTime.ofInstant(instant, ZoneOffset.UTC); - } - } diff --git a/core/base/src/main/java/com/nubeiot/core/utils/ExecutorHelpers.java b/core/base/src/main/java/com/nubeiot/core/utils/ExecutorHelpers.java index 56efdce42..41fb10091 100644 --- a/core/base/src/main/java/com/nubeiot/core/utils/ExecutorHelpers.java +++ b/core/base/src/main/java/com/nubeiot/core/utils/ExecutorHelpers.java @@ -16,6 +16,18 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ExecutorHelpers { + public static void blocking(@NonNull Vertx vertx, @NonNull Runnable callable) { + vertx.executeBlocking(future -> { + try { + callable.run(); + } catch (RuntimeException e) { + future.fail(e); + } finally { + future.complete(); + } + }, res -> {}); + } + public static Single blocking(@NonNull Vertx vertx, @NonNull Callable callable) { return Single.fromCallable(callable).subscribeOn(RxHelper.blockingScheduler(vertx)); } diff --git a/core/base/src/main/java/com/nubeiot/core/utils/FileUtils.java b/core/base/src/main/java/com/nubeiot/core/utils/FileUtils.java index 6c052dff5..d42d03497 100644 --- a/core/base/src/main/java/com/nubeiot/core/utils/FileUtils.java +++ b/core/base/src/main/java/com/nubeiot/core/utils/FileUtils.java @@ -98,7 +98,7 @@ public static Path toPath(String filePath, String classpathFile) { return Strings.isBlank(filePath) ? getClasspathFile(classpathFile) : toPath(filePath); } - private static Path getClasspathFile(String classpathFile) { + public static Path getClasspathFile(String classpathFile) { final Path fileInWorkingDir = Paths.get(".", classpathFile); if (fileInWorkingDir.toFile().exists()) { return fileInWorkingDir; @@ -310,4 +310,11 @@ public static String getExtension(String filename) { .orElse(""); } + public static String withoutExtension(String filename) { + return Optional.ofNullable(filename) + .filter(f -> f.contains(".")) + .map(f -> f.substring(0, filename.lastIndexOf("."))) + .orElse(""); + } + } diff --git a/core/installer/build.gradle b/core/installer/build.gradle index 1b49c2a09..ee5f9f96e 100644 --- a/core/installer/build.gradle +++ b/core/installer/build.gradle @@ -10,6 +10,7 @@ dependencies { compile project(':core:auth') compile project(':core:sql') compile project(':core:micro') + compile project(':core:archiver') compile project(':eventbus:edge') compile project.deps.database.h2 compile "io.vertx:vertx-maven-service-factory:$project.versions.vertx" diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java index 3c005f130..1e0c06bbe 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java @@ -35,15 +35,15 @@ import com.nubeiot.edge.installer.model.Keys; import com.nubeiot.edge.installer.model.Tables; import com.nubeiot.edge.installer.model.dto.RequestedServiceData; -import com.nubeiot.edge.installer.model.tables.daos.TblModuleDao; -import com.nubeiot.edge.installer.model.tables.daos.TblRemoveHistoryDao; -import com.nubeiot.edge.installer.model.tables.daos.TblTransactionDao; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblRemoveHistory; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationHistoryDao; +import com.nubeiot.edge.installer.model.tables.daos.DeployTransactionDao; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplicationHistory; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; import com.nubeiot.edge.installer.repository.InstallerRepository; -import com.nubeiot.edge.installer.service.AppDeployer; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.InstallerApiIndex; import lombok.AccessLevel; @@ -92,29 +92,29 @@ public final Single before() { return this; } - public final TblModuleDao moduleDao() { - return dao(TblModuleDao.class); + public final ApplicationDao applicationDao() { + return dao(ApplicationDao.class); } - public final TblTransactionDao transDao() { - return dao(TblTransactionDao.class); + public final DeployTransactionDao transDao() { + return dao(DeployTransactionDao.class); } - final Single> getModulesWhenBootstrap() { - return moduleDao().findManyByState(Arrays.asList(State.NONE, State.ENABLED)); + final Single> getModulesWhenBootstrap() { + return applicationDao().findManyByState(Arrays.asList(State.NONE, State.ENABLED)); } final InstallerEntityHandler initDeployer() { - final AppDeployer appDeployer = sharedData(SHARED_APP_DEPLOYER_CFG); - appDeployer.register(this); + final AppDeployerDefinition definition = sharedData(SHARED_APP_DEPLOYER_CFG); + definition.register(this); return this; } - protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule tblModule, AppConfig appConfig) { + protected AppConfig transformAppConfig(RepositoryConfig repoConfig, IApplication tblModule, AppConfig appConfig) { return appConfig; } - protected TblModule decorateModule(TblModule module) { + protected Application decorateModule(Application module) { final OffsetDateTime now = DateTimes.now(); return module.setCreatedAt(now).setModifiedAt(now); } @@ -128,21 +128,21 @@ Single addBuiltinApps(InstallerConfig config) { return Observable.fromIterable(config.getBuiltinApps()) .map(serviceData -> createTblModule(dataDir, config.getRepoConfig(), serviceData)) .map(this::decorateModule) - .collect(ArrayList::new, ArrayList::add) - .flatMap(list -> dao(TblModuleDao.class).insert(list)) + .collect(ArrayList::new, ArrayList::add) + .flatMap(list -> dao(ApplicationDao.class).insert(list)) .map(r -> new JsonObject().put("results", "Inserted " + r + " app module record(s)")); } - private TblModule createTblModule(Path dataDir, RepositoryConfig repoConfig, RequestedServiceData serviceData) { + private Application createTblModule(Path dataDir, RepositoryConfig repoConfig, RequestedServiceData serviceData) { ModuleTypeRule rule = sharedData(SHARED_MODULE_RULE); - ITblModule tblModule = rule.parse(serviceData.getMetadata()); + IApplication tblModule = rule.parse(serviceData.getMetadata()); AppConfig appConfig = transformAppConfig(repoConfig, tblModule, serviceData.getAppConfig()); - return (TblModule) rule.parse(dataDir, tblModule, appConfig).setState(State.NONE); + return (Application) rule.parse(dataDir, tblModule, appConfig).setState(State.NONE); } Single transitionPendingModules() { bootstrap = EventAction.MIGRATE; - final TblModuleDao dao = moduleDao(); + final ApplicationDao dao = applicationDao(); return dao.findManyByState(Collections.singletonList(State.PENDING)) .flattenAsObservable(pendingModules -> pendingModules) .flatMapMaybe(m -> genericQuery().executeAny(context -> getLastWipTransaction(m, context)) @@ -154,17 +154,17 @@ Single transitionPendingModules() { .map(r -> new JsonObject().put("results", r)); } - private Optional getLastWipTransaction(TblModule module, DSLContext dsl) { + private Optional getLastWipTransaction(Application module, DSLContext dsl) { return Optional.ofNullable(dsl.select() - .from(Tables.TBL_TRANSACTION) - .where(DSL.field(Tables.TBL_TRANSACTION.MODULE_ID).eq(module.getServiceId())) - .and(DSL.field(Tables.TBL_TRANSACTION.STATUS).eq(Status.WIP)) - .orderBy(Tables.TBL_TRANSACTION.MODIFIED_AT.desc()) + .from(Tables.APPLICATION) + .where(DSL.field(Tables.APPLICATION.APP_ID).eq(module.getAppId())) + .and(DSL.field(Tables.DEPLOY_TRANSACTION.STATUS).eq(Status.WIP)) + .orderBy(Tables.DEPLOY_TRANSACTION.MODIFIED_AT.desc()) .limit(1) - .fetchOneInto(TblTransaction.class)); + .fetchOneInto(DeployTransaction.class)); } - private TblModule checkingTransaction(TblModule module, TblTransaction transaction) { + private Application checkingTransaction(Application module, DeployTransaction transaction) { if (transaction.getEvent() == EventAction.CREATE || transaction.getEvent() == EventAction.INIT) { return module.setState(State.ENABLED); } @@ -173,14 +173,15 @@ private TblModule checkingTransaction(TblModule module, TblTransaction transacti if (Objects.isNull(prevMeta)) { return module.setState(State.ENABLED); } - return module.setState(new TblModule(prevMeta).getState() == State.DISABLED ? State.DISABLED : State.NONE); + return module.setState( + new Application(prevMeta).getState() == State.DISABLED ? State.DISABLED : State.NONE); } return module.setState(State.DISABLED); } private Single> findHistoryTransactionById(String transactionId) { - return dao(TblRemoveHistoryDao.class).findOneById(transactionId) - .map(optional -> optional.map(ITblRemoveHistory::toJson)); + return dao(ApplicationHistoryDao.class).findOneById(transactionId) + .map(optional -> optional.map(IApplicationHistory::toJson)); } public final Single> findTransactionById(String transactionId) { @@ -190,20 +191,20 @@ public final Single> findTransactionById(String transaction : this.findHistoryTransactionById(transactionId)); } - public final Single> findTransactionByModuleId(String moduleId) { + public final Single> findTransactionByModuleId(String moduleId) { return transDao().queryExecutor() - .findMany(dsl -> dsl.selectFrom(Tables.TBL_TRANSACTION) - .where(DSL.field(Tables.TBL_TRANSACTION.MODULE_ID).eq(moduleId)) - .orderBy(Tables.TBL_TRANSACTION.ISSUED_AT.desc())); + .findMany(dsl -> dsl.selectFrom(Tables.DEPLOY_TRANSACTION) + .where(DSL.field(Tables.DEPLOY_TRANSACTION.APP_ID).eq(moduleId)) + .orderBy(Tables.DEPLOY_TRANSACTION.ISSUED_AT.desc())); } public final Single> findOneTransactionByModuleId(String moduleId) { return transDao().queryExecutor() - .findOne(dsl -> dsl.selectFrom(Tables.TBL_TRANSACTION) - .where(DSL.field(Tables.TBL_TRANSACTION.MODULE_ID).eq(moduleId)) - .orderBy(Tables.TBL_TRANSACTION.ISSUED_AT.desc()) + .findOne(dsl -> dsl.selectFrom(Tables.DEPLOY_TRANSACTION) + .where(DSL.field(Tables.DEPLOY_TRANSACTION.APP_ID).eq(moduleId)) + .orderBy(Tables.DEPLOY_TRANSACTION.ISSUED_AT.desc()) .limit(1)) - .map(optional -> optional.map(TblTransaction::toJson)); + .map(optional -> optional.map(DeployTransaction::toJson)); } @Override diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java index ea40c2d28..13dc677c7 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java @@ -15,7 +15,7 @@ final class InstallerSchemaHandler implements SchemaHandler { @Override public @NonNull Table table() { - return Tables.TBL_MODULE; + return Tables.APPLICATION; } @Override diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java index f96435aaa..53f1f8f4e 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java @@ -16,7 +16,7 @@ import com.nubeiot.core.sql.SqlContext; import com.nubeiot.core.sql.SqlProvider; import com.nubeiot.edge.installer.loader.ModuleTypeRule; -import com.nubeiot.edge.installer.service.AppDeployer; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.AppDeploymentWorkflow; import com.nubeiot.edge.installer.service.InstallerService; @@ -40,7 +40,7 @@ public void start() { final ModuleTypeRule moduleRule = getModuleRuleProvider().get(); this.addSharedData(InstallerEntityHandler.SHARED_INSTALLER_CFG, installerConfig) .addSharedData(InstallerEntityHandler.SHARED_MODULE_RULE, moduleRule) - .addSharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG, appDeployer()) + .addSharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG, appDeployerDefinition()) .addProvider(new SqlProvider<>(entityHandlerClass()), this::sqlHandler) .addProvider(new MicroserviceProvider(), ctx -> microContext = (MicroContext) ctx) .registerSuccessHandler(v -> publishApis(microContext).flatMap(r -> deployAppModules()).subscribe(r -> { @@ -58,7 +58,7 @@ public void start() { protected abstract Supplier getModuleRuleProvider(); @NonNull - protected abstract AppDeployer appDeployer(); + protected abstract AppDeployerDefinition appDeployerDefinition(); @NonNull protected abstract Supplier> services(@NonNull InstallerEntityHandler handler); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypeRule.java b/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypeRule.java index 5ae555971..f58f2af43 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypeRule.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypeRule.java @@ -15,8 +15,8 @@ import com.nubeiot.core.NubeConfig; import com.nubeiot.core.NubeConfig.AppConfig; import com.nubeiot.core.utils.FileUtils; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; import lombok.AccessLevel; import lombok.NonNull; @@ -31,24 +31,24 @@ public ModuleTypeRule() { rules = new HashMap<>(); } - public ITblModule parse(@NonNull Path dataDir, @NonNull JsonObject metadata, AppConfig appConfig) { - ITblModule tblModule = parse(metadata); - tblModule = tblModule.setAppConfig(appConfig.toJson()); - tblModule = tblModule.setSystemConfig(computeAppSystemConfig(dataDir, tblModule.getServiceId())); - return tblModule; + public IApplication parse(@NonNull Path dataDir, @NonNull JsonObject metadata, AppConfig appConfig) { + IApplication application = parse(metadata); + application = application.setAppConfig(appConfig.toJson()); + application = application.setSystemConfig(computeAppSystemConfig(dataDir, application.getAppId())); + return application; } - public ITblModule parse(JsonObject metadata) { + public IApplication parse(JsonObject metadata) { ModuleType moduleType = ModuleType.factory(metadata.getString("service_type")); String serviceId = metadata.getString("service_id"); JsonObject module = Objects.isNull(serviceId) ? moduleType.serialize(metadata, this) : metadata; - return new TblModule().fromJson(module); + return new Application().fromJson(module); } - public ITblModule parse(@NonNull Path dataDir, @NonNull ITblModule tblModule, AppConfig appConfig) { - tblModule = tblModule.setAppConfig(appConfig.toJson()); - tblModule = tblModule.setSystemConfig(computeAppSystemConfig(dataDir, tblModule.getServiceId())); - return tblModule; + public IApplication parse(@NonNull Path dataDir, @NonNull IApplication application, AppConfig appConfig) { + application = application.setAppConfig(appConfig.toJson()); + application = application.setSystemConfig(computeAppSystemConfig(dataDir, application.getAppId())); + return application; } private JsonObject computeAppSystemConfig(@NonNull Path parentDataDir, String serviceId) { diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java b/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java index 859ed5b84..f25e33b5c 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java @@ -30,7 +30,7 @@ import com.nubeiot.edge.installer.loader.ModuleType; import com.nubeiot.edge.installer.model.Tables; import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; -import com.nubeiot.edge.installer.model.tables.records.TblModuleRecord; +import com.nubeiot.edge.installer.model.tables.records.ApplicationRecord; import lombok.NonNull; @@ -57,18 +57,18 @@ public Single search(RequestData requestData) throws NubeException { .map(results -> new JsonObject().put("services", results)); } - private Single excludeData(TblModuleRecord rec) { - final JsonObject cfg = PreDeploymentResult.filterOutSensitiveConfig(rec.getServiceId(), rec.getAppConfig()); + private Single excludeData(ApplicationRecord rec) { + final JsonObject cfg = PreDeploymentResult.filterOutSensitiveConfig(rec.getAppId(), rec.getAppConfig()); return Single.just(rec.setAppConfig(cfg).setSystemConfig(null).toJson()); } private JsonObject validateFilter(JsonObject filter) { //TODO fields name, depends object -> validate method JsonObject sqlData = new JsonObject(filter.getMap()); - String state = filter.getString(Tables.TBL_MODULE.STATE.getName().toLowerCase()); + String state = filter.getString(Tables.APPLICATION.STATE.getName().toLowerCase()); if (Strings.isNotBlank(state)) { try { - sqlData.put(Tables.TBL_MODULE.STATE.getName().toLowerCase(), State.valueOf(state)); + sqlData.put(Tables.APPLICATION.STATE.getName().toLowerCase(), State.valueOf(state)); } catch (IllegalArgumentException e) { throw new NubeException(ErrorCode.INVALID_ARGUMENT, "Invalid state", e); } @@ -87,11 +87,11 @@ private JsonObject validateFilter(JsonObject filter) { } @SuppressWarnings( {"unchecked", "rawtypes"}) - private List filter(JsonObject filter, Pagination pagination, DSLContext context) { - SelectConditionStep sql = context.selectFrom(Tables.TBL_MODULE) - .where(DSL.field(Tables.TBL_MODULE.SERVICE_TYPE) - .eq(ModuleType.JAVA)); - Set fieldNames = Arrays.stream(Tables.TBL_MODULE.fields()) + private List filter(JsonObject filter, Pagination pagination, DSLContext context) { + SelectConditionStep sql = context.selectFrom(Tables.APPLICATION) + .where(DSL.field(Tables.APPLICATION.SERVICE_TYPE) + .eq(ModuleType.JAVA)); + Set fieldNames = Arrays.stream(Tables.APPLICATION.fields()) .map(Field::getName) .collect(Collectors.toSet()); filter.getMap() @@ -99,22 +99,22 @@ private List filter(JsonObject filter, Pagination pagination, D .parallelStream() .filter(entry -> fieldNames.contains(entry.getKey())) .forEach(entry -> { - Field field = Tables.TBL_MODULE.field(entry.getKey()); + Field field = Tables.APPLICATION.field(entry.getKey()); sql.and(field.eq(entry.getValue())); }); final Instant from = filter.getInstant("from"); if (Objects.nonNull(from)) { - sql.and(DSL.field(Tables.TBL_MODULE.CREATED_AT).gt(DateTimes.from(from))); + sql.and(DSL.field(Tables.APPLICATION.CREATED_AT).gt(DateTimes.from(from))); } final Instant to = filter.getInstant("to"); if (Objects.nonNull(to)) { - sql.and(DSL.field(Tables.TBL_MODULE.CREATED_AT).lt(DateTimes.from(to))); + sql.and(DSL.field(Tables.APPLICATION.CREATED_AT).lt(DateTimes.from(to))); } return sql.limit(pagination.getPerPage()) .offset(((pagination.getPage() - 1) * pagination.getPerPage())) - .fetchInto(TblModuleRecord.class); + .fetchInto(ApplicationRecord.class); } } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployer.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java similarity index 56% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployer.java rename to core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java index 75b3eeac1..f39991475 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployer.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java @@ -9,18 +9,30 @@ /** * Application service deployer definition + * + * @since 1.0.0 */ -public interface AppDeployer extends Shareable { +public interface AppDeployerDefinition extends Shareable { - static AppDeployer create(@NonNull EventModel loaderEvent, @NonNull EventModel trackerEvent, - @NonNull EventModel finisherEvent) { - return new DefaultAppDeployer(loaderEvent, trackerEvent, finisherEvent); + /** + * Create app deployer definition. + * + * @param loaderEvent the loader event + * @param trackerEvent the tracker event + * @param finisherEvent the finisher event + * @return the app deployer + * @since 1.0.0 + */ + static AppDeployerDefinition create(@NonNull EventModel loaderEvent, @NonNull EventModel trackerEvent, + @NonNull EventModel finisherEvent) { + return new DefaultAppDeployerDefinition(loaderEvent, trackerEvent, finisherEvent); } /** * Defines deployment loader event * * @return loader event + * @since 1.0.0 */ @NonNull EventModel getLoaderEvent(); @@ -28,6 +40,7 @@ static AppDeployer create(@NonNull EventModel loaderEvent, @NonNull EventModel t * Defines tracker event after finish deploying * * @return tracker event + * @since 1.0.0 */ @NonNull EventModel getTrackerEvent(); @@ -35,6 +48,7 @@ static AppDeployer create(@NonNull EventModel loaderEvent, @NonNull EventModel t * Defines finisher event after finish deploy and update database * * @return finisher event + * @since 1.0.0 */ @NonNull EventModel getFinisherEvent(); @@ -42,6 +56,7 @@ static AppDeployer create(@NonNull EventModel loaderEvent, @NonNull EventModel t * Register event service * * @param entityHandler Entity handler + * @since 1.0.0 */ void register(@NonNull InstallerEntityHandler entityHandler); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java index fe39c5293..c1354955d 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java @@ -104,7 +104,7 @@ void doUnDeploy(PreDeploymentResult preResult, boolean silent, Future fu private void publishResult(PreDeploymentResult preResult, AsyncResult async) { final EventbusClient client = sharedData(SharedDataDelegate.SHARED_EVENTBUS); - final AppDeployer deployer = sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); + final AppDeployerDefinition deployer = sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); final JsonObject error = async.succeeded() ? new JsonObject() : ErrorMessage.parse(async.cause()).toJson(); final PostDeploymentResult pr = PostDeploymentResult.from(preResult, async.result(), error); client.fire(DeliveryEvent.from(deployer.getTrackerEvent(), new JsonObject().put("result", pr.toJson()))); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java index c009a7b8c..2a50a7482 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java @@ -29,12 +29,12 @@ import com.nubeiot.edge.installer.InstallerEntityHandler; import com.nubeiot.edge.installer.model.Tables; import com.nubeiot.edge.installer.model.dto.PostDeploymentResult; -import com.nubeiot.edge.installer.model.tables.daos.TblRemoveHistoryDao; -import com.nubeiot.edge.installer.model.tables.daos.TblTransactionDao; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblRemoveHistory; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblTransaction; -import com.nubeiot.edge.installer.model.tables.pojos.TblRemoveHistory; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationHistoryDao; +import com.nubeiot.edge.installer.model.tables.daos.DeployTransactionDao; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplicationHistory; +import com.nubeiot.edge.installer.model.tables.interfaces.IDeployTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.ApplicationHistory; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; import lombok.AccessLevel; import lombok.NonNull; @@ -57,7 +57,7 @@ public Single handle(@Param("result") PostDeploymentResult ? handleError(result) : handleSuccess(result); final EventbusClient client = sharedData(SharedDataDelegate.SHARED_EVENTBUS); - final AppDeployer deployer = sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); + final AppDeployerDefinition deployer = sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); return last.doOnSuccess(res -> client.fire( DeliveryEvent.from(deployer.getFinisherEvent(), new JsonObject().put("result", res.toJson())))); } @@ -68,20 +68,20 @@ private Single handleSuccess(@NonNull PostDeploymentResult final State state = StateMachine.instance().transition(res.getAction(), status, res.getToState()); final String serviceId = res.getServiceId(); if (State.UNAVAILABLE == state) { - final TblTransactionDao dao = entityHandler.transDao(); + final DeployTransactionDao dao = entityHandler.transDao(); LOGGER.info("INSTALLER::Removing service '{}' and its transactions...", serviceId); return dao.findOneById(res.getTransactionId()) .filter(Optional::isPresent) .map(Optional::get) - .defaultIfEmpty(new TblTransaction().setTransactionId(res.getTransactionId()) - .setModuleId(serviceId) - .setEvent(res.getAction())) + .defaultIfEmpty(new DeployTransaction().setTransactionId(res.getTransactionId()) + .setAppId(serviceId) + .setEvent(res.getAction())) .flatMapSingle(r -> createHistoryRecord(r.setStatus(status))) - .flatMap(his -> dao.deleteByCondition(Tables.TBL_TRANSACTION.MODULE_ID.eq(serviceId))) - .flatMap(r -> entityHandler.moduleDao().deleteById(serviceId).map(n -> r + n + 1)) + .flatMap(his -> dao.deleteByCondition(Tables.DEPLOY_TRANSACTION.APP_ID.eq(serviceId))) + .flatMap(r -> entityHandler.applicationDao().deleteById(serviceId).map(n -> r + n + 1)) .map(records -> PostDeploymentResult.from(res, state, records)); } - Map v = Collections.singletonMap(Tables.TBL_MODULE.DEPLOY_ID, res.getDeployId()); + Map v = Collections.singletonMap(Tables.APPLICATION.DEPLOY_ID, res.getDeployId()); final JDBCRXGenericQueryExecutor queryExecutor = entityHandler.genericQuery(); return queryExecutor.executeAny(c -> updateTransStatus(c, res.getTransactionId(), status, null)) .flatMap(r1 -> queryExecutor.executeAny(c -> updateModuleState(c, serviceId, state, v)) @@ -92,38 +92,38 @@ private Single handleSuccess(@NonNull PostDeploymentResult private Single handleError(@NonNull PostDeploymentResult res) { LOGGER.error("INSTALLER::Handle entities after error deployment..."); final JDBCRXGenericQueryExecutor query = entityHandler.genericQuery(); - final Map values = Collections.singletonMap(Tables.TBL_TRANSACTION.LAST_ERROR, res.getError()); + final Map values = Collections.singletonMap(Tables.DEPLOY_TRANSACTION.LAST_ERROR, res.getError()); return query.executeAny(c -> updateTransStatus(c, res.getTransactionId(), Status.FAILED, values)) .flatMap(r1 -> query.executeAny(c -> updateModuleState(c, res.getServiceId(), State.DISABLED, null)) .map(r2 -> r1 + r2)) .map(records -> PostDeploymentResult.from(res, State.DISABLED, records)); } - private Single createHistoryRecord(ITblTransaction transaction) { - ITblRemoveHistory history = this.convertToHistory(transaction); - return entityHandler.dao(TblRemoveHistoryDao.class).insert((TblRemoveHistory) history).map(i -> history); + private Single createHistoryRecord(IDeployTransaction transaction) { + IApplicationHistory history = this.convertToHistory(transaction); + return entityHandler.dao(ApplicationHistoryDao.class).insert((ApplicationHistory) history).map(i -> history); } private int updateModuleState(DSLContext context, String serviceId, State state, Map values) { - return context.update(Tables.TBL_MODULE) - .set(Tables.TBL_MODULE.STATE, state) - .set(Tables.TBL_MODULE.MODIFIED_AT, DateTimes.now()) + return context.update(Tables.APPLICATION) + .set(Tables.APPLICATION.STATE, state) + .set(Tables.APPLICATION.MODIFIED_AT, DateTimes.now()) .set(Objects.isNull(values) ? new HashMap<>() : values) - .where(Tables.TBL_MODULE.SERVICE_ID.eq(serviceId)) + .where(Tables.APPLICATION.APP_ID.eq(serviceId)) .execute(); } private int updateTransStatus(DSLContext context, String transId, Status status, Map values) { - return context.update(Tables.TBL_TRANSACTION) - .set(Tables.TBL_TRANSACTION.STATUS, status) - .set(Tables.TBL_TRANSACTION.MODIFIED_AT, DateTimes.now()) + return context.update(Tables.DEPLOY_TRANSACTION) + .set(Tables.DEPLOY_TRANSACTION.STATUS, status) + .set(Tables.DEPLOY_TRANSACTION.MODIFIED_AT, DateTimes.now()) .set(Objects.isNull(values) ? new HashMap<>() : values) - .where(Tables.TBL_TRANSACTION.TRANSACTION_ID.eq(transId)) + .where(Tables.DEPLOY_TRANSACTION.TRANSACTION_ID.eq(transId)) .execute(); } - private ITblRemoveHistory convertToHistory(ITblTransaction transaction) { - ITblRemoveHistory history = new TblRemoveHistory().fromJson(transaction.toJson()); + private IApplicationHistory convertToHistory(IDeployTransaction transaction) { + IApplicationHistory history = new ApplicationHistory().fromJson(transaction.toJson()); if (Objects.isNull(history.getIssuedAt())) { history.setIssuedAt(DateTimes.now()); } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java index a926ddbc4..5669413c2 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java @@ -27,9 +27,9 @@ import com.nubeiot.edge.installer.InstallerConfig; import com.nubeiot.edge.installer.InstallerEntityHandler; import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; import lombok.NonNull; @@ -38,28 +38,28 @@ public final class AppDeploymentWorkflow { private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentWorkflow.class); private final InstallerEntityHandler entityHandler; - private final AppDeployer deployer; + private final AppDeployerDefinition definition; public AppDeploymentWorkflow(InstallerEntityHandler entityHandler) { this.entityHandler = entityHandler; - this.deployer = entityHandler.sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); + this.definition = entityHandler.sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); } - public Single process(ITblModule module, EventAction action) { + public Single process(IApplication module, EventAction action) { return process(Collections.singleton(module), action).firstOrError(); } - public Observable process(Collection modules, EventAction action) { + public Observable process(Collection modules, EventAction action) { return Observable.fromIterable(modules).flatMapSingle(module -> processDeployment(module, action)); } - private Single processDeployment(ITblModule module, EventAction action) { - LOGGER.info("INSTALLER handle for {}::::{}", action, module.getServiceId()); + private Single processDeployment(IApplication module, EventAction action) { + LOGGER.info("INSTALLER handle for {}::::{}", action, module.getAppId()); return createPreDeployment(module, action).doOnSuccess(this::deployModule).map(PreDeploymentResult::toResponse); } - private Single createPreDeployment(ITblModule req, EventAction action) { - LOGGER.info("INSTALLER create pre-deployment for {}::::{}", action, req.getServiceId()); + private Single createPreDeployment(IApplication req, EventAction action) { + LOGGER.info("INSTALLER create pre-deployment for {}::::{}", action, req.getAppId()); InstallerConfig config = entityHandler.sharedData(InstallerEntityHandler.SHARED_INSTALLER_CFG); if (EventAction.CREATE == action || EventAction.INIT == action || (EventAction.MIGRATE == action && State.PENDING == req.getState())) { @@ -75,12 +75,13 @@ private Single createPreDeployment(ITblModule req, EventAct .flatMapSingle(m -> persistPreDeployResult(req, action, m)); } - private Single persistPreDeployResult(@NonNull ITblModule request, @NonNull EventAction action, - @NonNull ITblModule dbEntity) { - final TblModule cloneDb = new TblModule(dbEntity); + private Single persistPreDeployResult(@NonNull IApplication request, + @NonNull EventAction action, + @NonNull IApplication dbEntity) { + final Application cloneDb = new Application(dbEntity); final State prevState = EventAction.CREATE == action ? State.NONE : dbEntity.getState(); final State toState = Optional.ofNullable(request.getState()).orElse(dbEntity.getState()); - Maybe into = Maybe.empty(); + Maybe into = Maybe.empty(); if (EventAction.CREATE == action) { into = Maybe.fromSingle(markModuleInsert(cloneDb)); } @@ -103,19 +104,19 @@ private void deployModule(PreDeploymentResult preDeployResult) { LOGGER.info("INSTALLER trigger deploying for {}::::{}", action, preDeployResult.getServiceId()); preDeployResult.setSilent(EventAction.REMOVE == action && State.DISABLED == preDeployResult.getPrevState()); entityHandler.eventClient() - .fire(DeliveryEvent.from(deployer.getLoaderEvent(), action, preDeployResult.toRequestData())); + .fire(DeliveryEvent.from(definition.getLoaderEvent(), action, preDeployResult.toRequestData())); } - private PreDeploymentResult createPreDeployResult(ITblModule module, String transactionId, EventAction action, + private PreDeploymentResult createPreDeployResult(IApplication module, String transactionId, EventAction action, State prevState, State targetState) { return PreDeploymentResult.builder() .transactionId(transactionId) .action(action == EventAction.MIGRATE ? EventAction.UPDATE : action) .prevState(prevState) .targetState(targetState) - .serviceId(module.getServiceId()) + .serviceId(module.getAppId()) .serviceFQN(module.getServiceType() - .generateFQN(module.getServiceId(), module.getVersion(), + .generateFQN(module.getAppId(), module.getVersion(), module.getServiceName())) .deployId(module.getDeployId()) .appConfig(module.getAppConfig()) @@ -124,15 +125,15 @@ private PreDeploymentResult createPreDeployResult(ITblModule module, String tran .build(); } - private Single> validateModuleState(ITblModule module, EventAction action) { - LOGGER.info("INSTALLER validate service state {}::::{}", action, module.getServiceId()); - return entityHandler.moduleDao() - .findOneById(module.getServiceId()) + private Single> validateModuleState(IApplication module, EventAction action) { + LOGGER.info("INSTALLER validate service state {}::::{}", action, module.getAppId()); + return entityHandler.applicationDao() + .findOneById(module.getAppId()) .map(o -> validateModuleState(o.orElse(null), action, module.getState())); } - private Single createTransaction(EventAction action, ITblModule module) { - LOGGER.info("INSTALLER create transaction for {}::::{}", action, module.getServiceId()); + private Single createTransaction(EventAction action, IApplication module) { + LOGGER.info("INSTALLER create transaction for {}::::{}", action, module.getAppId()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("INSTALLER previous module state: {}", module.toJson()); } @@ -142,43 +143,43 @@ private Single createTransaction(EventAction action, ITblModule module) // TODO replace with POJO constant later metadata.remove("system_config"); metadata.remove("app_config"); - final TblTransaction transaction = new TblTransaction().setTransactionId(transactionId) - .setModuleId(module.getServiceId()) - .setStatus(Status.WIP) - .setEvent(action) - .setIssuedAt(now) - .setModifiedAt(now) - .setRetry(0) - .setPrevMetadata(metadata) - .setPrevSystemConfig(module.getSystemConfig()) - .setPrevAppConfig(module.getAppConfig()); + final DeployTransaction transaction = new DeployTransaction().setTransactionId(transactionId) + .setAppId(module.getAppId()) + .setStatus(Status.WIP) + .setEvent(action) + .setIssuedAt(now) + .setModifiedAt(now) + .setRetry(0) + .setPrevMetadata(metadata) + .setPrevSystemConfig(module.getSystemConfig()) + .setPrevAppConfig(module.getAppConfig()); return entityHandler.transDao().insert(transaction).map(i -> transactionId); } - private Single markModuleInsert(ITblModule module) { - LOGGER.debug("INSTALLER mark service {} to create...", module.getServiceId()); + private Single markModuleInsert(IApplication module) { + LOGGER.debug("INSTALLER mark service {} to create...", module.getAppId()); OffsetDateTime now = DateTimes.now(); - return entityHandler.moduleDao() - .insert((TblModule) module.setCreatedAt(now).setModifiedAt(now).setState(State.PENDING)) + return entityHandler.applicationDao() + .insert((Application) module.setCreatedAt(now).setModifiedAt(now).setState(State.PENDING)) .map(i -> module); } - private Single markModuleModify(ITblModule module, ITblModule oldOne, boolean isUpdated) { - LOGGER.debug("INSTALLER mark service {} to modify...", module.getServiceId()); - ITblModule into = updateModule(oldOne, module, isUpdated); - return entityHandler.moduleDao() - .update((TblModule) into.setState(State.PENDING).setModifiedAt(DateTimes.now())) + private Single markModuleModify(IApplication module, IApplication oldOne, boolean isUpdated) { + LOGGER.debug("INSTALLER mark service {} to modify...", module.getAppId()); + IApplication into = updateModule(oldOne, module, isUpdated); + return entityHandler.applicationDao() + .update((Application) into.setState(State.PENDING).setModifiedAt(DateTimes.now())) .map(ignore -> oldOne); } - private Single markModuleDelete(ITblModule module) { - LOGGER.debug("INSTALLER mark service {} to delete...", module.getServiceId()); - return entityHandler.moduleDao() - .update((TblModule) module.setState(State.PENDING).setModifiedAt(DateTimes.now())) + private Single markModuleDelete(IApplication module) { + LOGGER.debug("INSTALLER mark service {} to delete...", module.getAppId()); + return entityHandler.applicationDao() + .update((Application) module.setState(State.PENDING).setModifiedAt(DateTimes.now())) .map(ignore -> module); } - private ITblModule updateModule(@NonNull ITblModule old, @NonNull ITblModule newOne, boolean isUpdated) { + private IApplication updateModule(@NonNull IApplication old, @NonNull IApplication newOne, boolean isUpdated) { if (Strings.isBlank(newOne.getVersion()) && isUpdated) { throw new IllegalArgumentException("Service version is mandatory"); } @@ -194,15 +195,14 @@ private ITblModule updateModule(@NonNull ITblModule old, @NonNull ITblModule new return old; } - private Optional validateModuleState(ITblModule findModule, EventAction action, State targetState) { + private Optional validateModuleState(IApplication findModule, EventAction action, State targetState) { StateMachine.instance().validate(findModule, action, "service"); if (Objects.nonNull(findModule)) { final State target = action == EventAction.INIT ? State.ENABLED : Optional.ofNullable(targetState).orElse(findModule.getState()); StateMachine.instance() - .validateConflict(findModule.getState(), action, "service " + findModule.getServiceId(), - target); + .validateConflict(findModule.getState(), action, "service " + findModule.getAppId(), target); return Optional.of(findModule); } return Optional.empty(); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/ModuleService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java similarity index 82% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/ModuleService.java rename to core/installer/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java index 2272aed4e..071ac4dee 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/ModuleService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java @@ -17,9 +17,9 @@ import com.nubeiot.edge.installer.loader.ModuleTypeRule; import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; import com.nubeiot.edge.installer.model.dto.RequestedServiceData; -import com.nubeiot.edge.installer.model.tables.daos.TblModuleDao; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; import com.nubeiot.edge.installer.search.LocalServiceSearch; import lombok.AccessLevel; @@ -27,7 +27,7 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public abstract class ModuleService implements InstallerService { +public abstract class ApplicationService implements InstallerService { @NonNull private final InstallerEntityHandler entityHandler; @@ -37,7 +37,7 @@ public final String servicePath() { } public final String paramPath() { - return "service_id"; + return "app_id"; } @Override @@ -60,7 +60,8 @@ public Single getOne(RequestData data) { if (Strings.isBlank(serviceId)) { throw new IllegalArgumentException("Service id is mandatory"); } - return entityHandler.dao(TblModuleDao.class).findOneById(serviceId) + return entityHandler.dao(ApplicationDao.class) + .findOneById(serviceId) .map(o -> o.map(this::removeCredentialsInAppConfig)) .filter(Optional::isPresent) .map(Optional::get) @@ -70,8 +71,8 @@ public Single getOne(RequestData data) { @EventContractor(action = EventAction.PATCH, returnType = Single.class) public Single patch(RequestData data) { - ITblModule module = createTblModule(data.body()); - if (Strings.isBlank(module.getServiceId())) { + IApplication module = createTblModule(data.body()); + if (Strings.isBlank(module.getAppId())) { throw new IllegalArgumentException("Service id is mandatory"); } return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.PATCH); @@ -79,8 +80,8 @@ public Single patch(RequestData data) { @EventContractor(action = EventAction.UPDATE, returnType = Single.class) public Single update(RequestData data) { - ITblModule module = validate(data.body()); - if (Strings.isBlank(module.getServiceName()) && Strings.isBlank(module.getServiceId())) { + IApplication module = validate(data.body()); + if (Strings.isBlank(module.getServiceName()) && Strings.isBlank(module.getAppId())) { throw new IllegalArgumentException("Provide at least service id or service name"); } return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.UPDATE); @@ -88,8 +89,8 @@ public Single update(RequestData data) { @EventContractor(action = EventAction.REMOVE, returnType = Single.class) public Single remove(RequestData data) { - ITblModule module = new TblModule().setServiceId(data.body().getString(paramPath())); - if (Strings.isBlank(module.getServiceId())) { + IApplication module = new Application().setAppId(data.body().getString(paramPath())); + if (Strings.isBlank(module.getAppId())) { throw new IllegalArgumentException("Service id is mandatory"); } return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.REMOVE); @@ -100,13 +101,13 @@ public Single create(RequestData data) { return new AppDeploymentWorkflow(entityHandler).process(validate(data.body()), EventAction.CREATE); } - private JsonObject removeCredentialsInAppConfig(TblModule record) { - record.setAppConfig(PreDeploymentResult.filterOutSensitiveConfig(record.getServiceId(), record.getAppConfig())); + private JsonObject removeCredentialsInAppConfig(Application record) { + record.setAppConfig(PreDeploymentResult.filterOutSensitiveConfig(record.getAppId(), record.getAppConfig())); return record.toJson(); } - private ITblModule validate(@NonNull JsonObject body) { - ITblModule module = createTblModule(body); + private IApplication validate(@NonNull JsonObject body) { + IApplication module = createTblModule(body); if (Strings.isBlank(module.getServiceName())) { throw new IllegalArgumentException("Service name is mandatory"); } @@ -116,7 +117,7 @@ private ITblModule validate(@NonNull JsonObject body) { return module; } - private ITblModule createTblModule(JsonObject body) { + private IApplication createTblModule(JsonObject body) { String serviceId = body.getString(paramPath()); body.remove(paramPath()); RequestedServiceData serviceData = body.isEmpty() diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/BackupByAppService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/BackupByAppService.java new file mode 100644 index 000000000..7c90e0365 --- /dev/null +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/BackupByAppService.java @@ -0,0 +1,160 @@ +package com.nubeiot.edge.installer.service; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.jooq.Field; + +import io.reactivex.Single; +import io.vertx.core.http.HttpMethod; +import io.vertx.core.json.JsonObject; + +import com.nubeiot.core.NubeConfig; +import com.nubeiot.core.archiver.AsyncZipFolder; +import com.nubeiot.core.archiver.ZipArgument; +import com.nubeiot.core.archiver.ZipNotificationHandler; +import com.nubeiot.core.archiver.ZipOutput; +import com.nubeiot.core.dto.RequestData; +import com.nubeiot.core.enums.Status; +import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventContractor; +import com.nubeiot.core.exceptions.ErrorData; +import com.nubeiot.core.http.base.event.ActionMethodMapping; +import com.nubeiot.core.sql.service.AbstractReferencingEntityService; +import com.nubeiot.core.sql.service.marker.EntityReferences; +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.utils.UUID64; +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.ApplicationBackup; +import com.nubeiot.edge.installer.service.InstallerApiIndex.ApplicationMetadata; +import com.nubeiot.edge.installer.service.InstallerApiIndex.BackupMetadata; + +import lombok.NonNull; + +/** + * Represents Backup service. + * + * @since 1.0.0 + */ +public abstract class BackupByAppService extends AbstractReferencingEntityService + implements InstallerService, ZipNotificationHandler { + + protected BackupByAppService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + + @Override + public BackupMetadata context() { + return BackupMetadata.INSTANCE; + } + + @Override + public final String servicePath() { + return "/:app_id/backup"; + } + + @Override + public final String paramPath() { + return "backup_id"; + } + + @Override + public final ActionMethodMapping methodMapping() { + final Map map = new HashMap<>(); + map.put(EventAction.BACKUP, HttpMethod.POST); + map.put(EventAction.GET_ONE, HttpMethod.GET); + return ActionMethodMapping.create(map); + } + + @Override + public final @NonNull Collection getAvailableEvents() { + return Stream.of(ZipNotificationHandler.super.getAvailableEvents(), + Arrays.asList(EventAction.BACKUP, EventAction.GET_ONE)) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + } + + @Override + public final EntityReferences referencedEntities() { + return new EntityReferences().add(ApplicationMetadata.INSTANCE); + } + + @EventContractor(action = EventAction.BACKUP, returnType = Single.class) + public final Single backup(@NonNull RequestData data) { + final String appId = Strings.requireNotBlank(data.body().getString("app_id"), "Missing application id"); + return entityHandler().dao(ApplicationDao.class) + .findOneById(appId) + .filter(Optional::isPresent) + .map(Optional::get) + .switchIfEmpty(Single.error(ApplicationMetadata.INSTANCE.notFound(appId))) + .flatMap(this::createBackupRecord) + .doOnSuccess(this::doBackup); + } + + @EventContractor(action = EventAction.NOTIFY, returnType = boolean.class) + public final boolean success(@NonNull ZipOutput result) { + final ApplicationBackup backup = context().parseFromRequest(result.getTrackingInfo()); + final String type = result.getTrackingInfo().getString("type"); + patch(RequestData.builder() + .body(backup.toJson() + .put("status", Status.SUCCESS) + .put(type, result.toJson(Collections.singleton("trackingInfo")))) + .build()); + return true; + } + + @EventContractor(action = EventAction.NOTIFY_ERROR, returnType = boolean.class) + public final boolean error(@NonNull ErrorData error) { + final ApplicationBackup backup = context().parseFromRequest(error.getExtraInfo()); + patch(RequestData.builder() + .body(backup.toJson().put("status", Status.FAILED).put("error", error.getError().toJson())) + .build()); + return true; + } + + protected @NonNull Path backupFolder() { + return entityHandler().dataDir().resolve("backup"); + } + + protected @NonNull Single createBackupRecord(@NonNull Application app) { + final ApplicationBackup backup = new ApplicationBackup().setAppId(app.getAppId()).setStatus(Status.INITIAL); + final String idField = jsonField(context().table().ID); + return create(RequestData.builder().body(backup.toJson()).build()).map( + json -> new JsonObject().put(context().requestKeyName(), UUID64.uuidToBase64(json.getString(idField))) + .put(jsonField(context().table().APP_ID), app.getAppId()) + .put(jsonField(context().table().INSTALLATION_DIR), app.getDeployLocation()) + .put(jsonField(context().table().DATA_DIR), + app.getSystemConfig().getString(NubeConfig.DATA_DIR))); + } + + protected void doBackup(@NonNull JsonObject record) { + final JsonObject info = new JsonObject().put(context().requestKeyName(), + record.getString(context().requestKeyName())) + .put(ApplicationMetadata.INSTANCE.requestKeyName(), + record.getString(ApplicationMetadata.INSTANCE.requestKeyName())); + final AsyncZipFolder zipper = AsyncZipFolder.builder() + .notifiedAddress(address()) + .transporter(entityHandler().eventClient()) + .build(); + // final String installationDirField = jsonField(context().table().INSTALLATION_DIR); + final String dataDirField = jsonField(context().table().DATA_DIR); + // zipper.run(ZipArgument.createDefault(info.put("type", installationDirField)), backupFolder(), + // Paths.get(installationDirField)); + zipper.zip(ZipArgument.createDefault(info.put("type", dataDirField)), backupFolder(), Paths.get(dataDirField)); + } + + private String jsonField(Field installation_dir) { + return context().table().getJsonField(installation_dir); + } + +} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployer.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java similarity index 91% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployer.java rename to core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java index 79fecab12..f9af152aa 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployer.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java @@ -9,7 +9,7 @@ @Getter @RequiredArgsConstructor -final class DefaultAppDeployer implements AppDeployer { +final class DefaultAppDeployerDefinition implements AppDeployerDefinition { @NonNull private final EventModel loaderEvent; diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java index a55cf46de..1fcf1e98a 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java @@ -2,8 +2,21 @@ import com.nubeiot.core.event.EventListener; +/** + * The interface Deployment service. + * + * @since 1.0.0 + */ public interface DeploymentService extends EventListener { + /** + * Gets shared data. + * + * @param Type of {@code data} + * @param dataKey the data key + * @return the data + * @since 1.0.0 + */ D sharedData(String dataKey); } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerApiIndex.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerApiIndex.java index 4d7f12348..ab23f42e5 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerApiIndex.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerApiIndex.java @@ -8,17 +8,21 @@ import com.nubeiot.core.sql.EntityMetadata; import com.nubeiot.core.sql.EntityMetadata.StringKeyEntity; +import com.nubeiot.core.sql.EntityMetadata.UUIDKeyEntity; import com.nubeiot.core.sql.MetadataIndex; import com.nubeiot.edge.installer.model.Tables; -import com.nubeiot.edge.installer.model.tables.daos.TblModuleDao; -import com.nubeiot.edge.installer.model.tables.daos.TblRemoveHistoryDao; -import com.nubeiot.edge.installer.model.tables.daos.TblTransactionDao; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblRemoveHistory; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; -import com.nubeiot.edge.installer.model.tables.records.TblModuleRecord; -import com.nubeiot.edge.installer.model.tables.records.TblRemoveHistoryRecord; -import com.nubeiot.edge.installer.model.tables.records.TblTransactionRecord; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationBackupDao; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationHistoryDao; +import com.nubeiot.edge.installer.model.tables.daos.DeployTransactionDao; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.ApplicationBackup; +import com.nubeiot.edge.installer.model.tables.pojos.ApplicationHistory; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; +import com.nubeiot.edge.installer.model.tables.records.ApplicationBackupRecord; +import com.nubeiot.edge.installer.model.tables.records.ApplicationHistoryRecord; +import com.nubeiot.edge.installer.model.tables.records.ApplicationRecord; +import com.nubeiot.edge.installer.model.tables.records.DeployTransactionRecord; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -35,34 +39,34 @@ default List index() { } @NoArgsConstructor(access = AccessLevel.PRIVATE) - final class AppServiceMetadata implements StringKeyEntity { + final class ApplicationMetadata implements StringKeyEntity { - public static final AppServiceMetadata INSTANCE = new AppServiceMetadata(); + public static final ApplicationMetadata INSTANCE = new ApplicationMetadata(); @Override - public @NonNull com.nubeiot.edge.installer.model.tables.TblModule table() { - return Tables.TBL_MODULE; + public @NonNull com.nubeiot.edge.installer.model.tables.Application table() { + return Tables.APPLICATION; } @Override - public @NonNull Class modelClass() { - return TblModule.class; + public @NonNull Class modelClass() { + return Application.class; } @Override - public @NonNull Class daoClass() { - return TblModuleDao.class; + public @NonNull Class daoClass() { + return ApplicationDao.class; } @Override - public @NonNull String requestKeyName() { return "transaction_id"; } + public @NonNull String requestKeyName() { return "app_id"; } @Override - public @NonNull String singularKeyName() { return "transaction"; } + public @NonNull String singularKeyName() { return "app"; } @Override public @NonNull List> orderFields() { - return Arrays.asList(table().STATE, table().SERVICE_TYPE, table().SERVICE_ID); + return Arrays.asList(table().STATE, table().SERVICE_TYPE, table().APP_ID); } } @@ -70,23 +74,23 @@ final class AppServiceMetadata implements StringKeyEntity { + implements StringKeyEntity { public static final TransactionMetadata INSTANCE = new TransactionMetadata(); @Override - public @NonNull com.nubeiot.edge.installer.model.tables.TblTransaction table() { - return Tables.TBL_TRANSACTION; + public @NonNull com.nubeiot.edge.installer.model.tables.DeployTransaction table() { + return Tables.DEPLOY_TRANSACTION; } @Override - public @NonNull Class modelClass() { - return TblTransaction.class; + public @NonNull Class modelClass() { + return DeployTransaction.class; } @Override - public @NonNull Class daoClass() { - return TblTransactionDao.class; + public @NonNull Class daoClass() { + return DeployTransactionDao.class; } @Override @@ -97,7 +101,7 @@ final class TransactionMetadata @Override public @NonNull List> orderFields() { - return Arrays.asList(table().MODULE_ID, table().MODIFIED_AT.desc()); + return Arrays.asList(table().APP_ID, table().MODIFIED_AT.desc()); } } @@ -105,23 +109,23 @@ final class TransactionMetadata @NoArgsConstructor(access = AccessLevel.PRIVATE) final class HistoryMetadata - implements StringKeyEntity { + implements StringKeyEntity { public static final HistoryMetadata INSTANCE = new HistoryMetadata(); @Override - public @NonNull com.nubeiot.edge.installer.model.tables.TblRemoveHistory table() { - return Tables.TBL_REMOVE_HISTORY; + public @NonNull com.nubeiot.edge.installer.model.tables.ApplicationHistory table() { + return Tables.APPLICATION_HISTORY; } @Override - public @NonNull Class modelClass() { - return TblRemoveHistory.class; + public @NonNull Class modelClass() { + return ApplicationHistory.class; } @Override - public @NonNull Class daoClass() { - return TblRemoveHistoryDao.class; + public @NonNull Class daoClass() { + return ApplicationHistoryDao.class; } @Override @@ -132,7 +136,42 @@ final class HistoryMetadata @Override public @NonNull List> orderFields() { - return Arrays.asList(table().MODULE_ID, table().MODIFIED_AT.desc()); + return Arrays.asList(table().APP_ID, table().MODIFIED_AT.desc()); + } + + } + + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + final class BackupMetadata + implements UUIDKeyEntity { + + public static final BackupMetadata INSTANCE = new BackupMetadata(); + + @Override + public @NonNull com.nubeiot.edge.installer.model.tables.ApplicationBackup table() { + return Tables.APPLICATION_BACKUP; + } + + @Override + public @NonNull Class modelClass() { + return ApplicationBackup.class; + } + + @Override + public @NonNull Class daoClass() { + return ApplicationBackupDao.class; + } + + @Override + public @NonNull String requestKeyName() { return "backup_id"; } + + @Override + public @NonNull String singularKeyName() { return "backup"; } + + @Override + public @NonNull List> orderFields() { + return Collections.singletonList(table().APP_ID); } } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java index f8325d886..ae62347f9 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java @@ -1,14 +1,12 @@ package com.nubeiot.edge.installer.service; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import io.vertx.core.http.HttpMethod; - -import com.nubeiot.core.event.EventAction; import com.nubeiot.core.http.base.EventHttpService; import com.nubeiot.core.http.base.Urls; import com.nubeiot.core.http.base.event.ActionMethodMapping; @@ -16,8 +14,22 @@ import com.nubeiot.core.utils.Reflections.ReflectionClass; import com.nubeiot.edge.installer.InstallerEntityHandler; +/** + * Represents Installer service. + * + * @since 1.0.0 + */ public interface InstallerService extends EventHttpService { + /** + * Create services. + * + * @param Type of {@code InstallerService} + * @param entityHandler the entity handler + * @param serviceClazz the service clazz + * @return set of {@code InstallerService} + * @since 1.0.0 + */ static Set createServices(InstallerEntityHandler entityHandler, Class serviceClazz) { final Map inputs = Collections.singletonMap(InstallerEntityHandler.class, entityHandler); @@ -27,19 +39,55 @@ static Set createServices(InstallerEntityHandler .collect(Collectors.toSet()); } - @Override - default Set definitions() { - Map map = ActionMethodMapping.CRUD_MAP.get(); - ActionMethodMapping actionMethodMap = ActionMethodMapping.create( - getAvailableEvents().stream().filter(map::containsKey).collect(Collectors.toMap(e -> e, map::get))); - return Collections.singleton( - EventMethodDefinition.create(Urls.combinePath(rootPath(), servicePath()), paramPath(), actionMethodMap)); + /** + * Defines Root path. + * + * @return Root path + * @since 1.0.0 + */ + default String rootPath() { + return "/installer"; } - String rootPath(); + /** + * Defines Application path. + * + * @return Application path + * @since 1.0.0 + */ + String appPath(); + /** + * Defines Service path. + * + * @return Service path + * @since 1.0.0 + */ String servicePath(); + /** + * Defines Param path. + * + * @return Param path + * @since 1.0.0 + */ String paramPath(); + @Override + default Set definitions() { + final String fullPath = Urls.combinePath(rootPath(), appPath(), servicePath()); + return Collections.singleton(EventMethodDefinition.create(fullPath, paramPath(), methodMapping())); + } + + /** + * Creates Event action Method mapping. + * + * @return the action method mapping. Defaults: {@link ActionMethodMapping#byCRUD(Collection)} + * @see ActionMethodMapping + * @since 1.0.0 + */ + default ActionMethodMapping methodMapping() { + return ActionMethodMapping.byCRUD(getAvailableEvents()); + } + } diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByModuleService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionByAppService.java similarity index 74% rename from edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByModuleService.java rename to core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionByAppService.java index 0ec6e39a9..0481a62a9 100644 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByModuleService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionByAppService.java @@ -1,4 +1,4 @@ -package com.nubeiot.edge.module.installer.service; +package com.nubeiot.edge.installer.service; import java.util.Collection; import java.util.Collections; @@ -13,35 +13,49 @@ import com.nubeiot.core.exceptions.NotFoundException; import com.nubeiot.core.utils.Strings; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblTransaction; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.interfaces.IDeployTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; +import lombok.AccessLevel; import lombok.NonNull; import lombok.RequiredArgsConstructor; -@RequiredArgsConstructor -public final class EdgeTransactionByModuleService implements EdgeInstallerService { +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class TransactionByAppService implements InstallerService { @NonNull private final InstallerEntityHandler entityHandler; + @Override + public @NonNull Collection getAvailableEvents() { + return Collections.singleton(EventAction.GET_LIST); + } + + @Override + public String servicePath() { + return "/:app_id/transaction"; + } + + @Override + public String paramPath() { + return null; + } + @EventContractor(action = EventAction.GET_LIST, returnType = Single.class) public Single getList(RequestData data) { - JsonObject filter = data.filter(); - boolean lastTransaction = Boolean.parseBoolean(filter.getString("last")); - ITblTransaction transaction = new TblTransaction().fromJson(data.body()); - if (Strings.isBlank(transaction.getModuleId())) { + final IDeployTransaction transaction = new DeployTransaction().fromJson(data.body()); + if (Strings.isBlank(transaction.getAppId())) { throw new IllegalArgumentException("Service id is mandatory"); } - if (lastTransaction) { - return this.entityHandler.findOneTransactionByModuleId(transaction.getModuleId()) + if (data.filter().parseBoolean("last")) { + return this.entityHandler.findOneTransactionByModuleId(transaction.getAppId()) .map(o -> o.orElseThrow(() -> new NotFoundException( - String.format("Not found service id '%s'", transaction.getModuleId())))) + String.format("Not found service id '%s'", transaction.getAppId())))) .map(this::removePrevSystemConfig) .map(transactions -> new JsonObject().put("transactions", new JsonArray().add(transactions))); } - return this.entityHandler.findTransactionByModuleId(transaction.getModuleId()) + return this.entityHandler.findTransactionByModuleId(transaction.getAppId()) .flattenAsObservable(transactions -> transactions) .flatMapSingle(trans -> Single.just(removePrevSystemConfig(trans.toJson()))) .toList() @@ -53,19 +67,4 @@ private JsonObject removePrevSystemConfig(JsonObject transaction) { return transaction; } - @Override - public @NonNull Collection getAvailableEvents() { - return Collections.singleton(EventAction.GET_LIST); - } - - @Override - public String servicePath() { - return "/:module_id/transactions"; - } - - @Override - public String paramPath() { - return null; - } - } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java b/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java index 4c686b8f1..dd8618d68 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java +++ b/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java @@ -10,12 +10,10 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.event.EventContractor; import com.nubeiot.core.exceptions.NotFoundException; -import com.nubeiot.core.exceptions.NubeException; -import com.nubeiot.core.exceptions.NubeException.ErrorCode; import com.nubeiot.core.utils.Strings; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblTransaction; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.interfaces.IDeployTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; import lombok.AccessLevel; import lombok.NonNull; @@ -27,30 +25,9 @@ public abstract class TransactionService implements InstallerService { @NonNull private final InstallerEntityHandler entityHandler; - @EventContractor(action = EventAction.GET_ONE, returnType = Single.class) - public Single getOne(RequestData data) { - JsonObject filter = data.filter(); - boolean systemCfg = Boolean.parseBoolean(filter.getString("system_cfg")); - ITblTransaction transaction = new TblTransaction().fromJson(data.body()); - if (Strings.isBlank(transaction.getTransactionId())) { - throw new NubeException(ErrorCode.INVALID_ARGUMENT, "Transaction Id cannot be blank"); - } - return this.entityHandler.findTransactionById(transaction.getTransactionId()) - .map(o -> o.orElseThrow(() -> new NotFoundException( - Strings.format("Not found transaction id '{0}'", transaction.getTransactionId())))) - .map(trans -> removePrevSystemConfig(trans, systemCfg)); - } - - private JsonObject removePrevSystemConfig(JsonObject transaction, boolean systemCfg) { - if (!systemCfg) { - transaction.remove("prev_system_config"); - } - return transaction; - } - @Override public final String servicePath() { - return "/transactions"; + return "/transaction"; } @Override @@ -63,4 +40,23 @@ public final String paramPath() { return Collections.singletonList(EventAction.GET_ONE); } + @EventContractor(action = EventAction.GET_ONE, returnType = Single.class) + public Single getOne(RequestData data) { + final boolean includeSystemCfg = data.filter().parseBoolean("system_cfg"); + final IDeployTransaction transaction = new DeployTransaction().fromJson(data.body()); + final String transactionId = Strings.requireNotBlank(transaction.getTransactionId(), + "Transaction Id cannot be blank"); + return this.entityHandler.findTransactionById(transactionId) + .map(o -> o.orElseThrow(() -> new NotFoundException( + Strings.format("Not found transaction id '{0}'", transactionId)))) + .map(trans -> removePrevSystemConfig(trans, includeSystemCfg)); + } + + private JsonObject removePrevSystemConfig(JsonObject transaction, boolean includeSystemCfg) { + if (!includeSystemCfg) { + transaction.remove("prev_system_config"); + } + return transaction; + } + } diff --git a/core/installer/src/main/resources/ddl/01_ddl.sql b/core/installer/src/main/resources/ddl/01_ddl.sql index 0c8b67ce3..ce84efea0 100644 --- a/core/installer/src/main/resources/ddl/01_ddl.sql +++ b/core/installer/src/main/resources/ddl/01_ddl.sql @@ -1,5 +1,5 @@ -CREATE TABLE IF NOT EXISTS tbl_module ( - service_id varchar(127) NOT NULL, +CREATE TABLE IF NOT EXISTS application ( + app_id varchar(127) NOT NULL, service_name varchar(127) NOT NULL, service_type varchar(15) NOT NULL, version varchar(31) NOT NULL, @@ -11,13 +11,13 @@ CREATE TABLE IF NOT EXISTS tbl_module ( app_config_json text, system_config_json text, deploy_location varchar(500), - CONSTRAINT Pk_tbl_module PRIMARY KEY ( service_id ), - CONSTRAINT Unique_tbl_module UNIQUE ( service_name, service_type ) + CONSTRAINT Pk_application PRIMARY KEY ( app_id ), + CONSTRAINT Unique_application UNIQUE ( service_name, service_type ) ); -CREATE TABLE IF NOT EXISTS tbl_transaction ( +CREATE TABLE IF NOT EXISTS deploy_transaction ( transaction_id varchar(63) NOT NULL, - module_id varchar(127) NOT NULL, + app_id varchar(127) NOT NULL, event varchar(15) NOT NULL, status varchar(15) NOT NULL, issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -29,17 +29,17 @@ CREATE TABLE IF NOT EXISTS tbl_transaction ( prev_system_config_json text, last_error_json text, retry integer NOT NULL DEFAULT 0, - CONSTRAINT Pk_tbl_transaction PRIMARY KEY ( transaction_id ), - FOREIGN KEY ( module_id ) REFERENCES tbl_module( service_id ) + CONSTRAINT Pk_deploy_transaction PRIMARY KEY ( transaction_id ), + FOREIGN KEY ( app_id ) REFERENCES application( app_id ) ); -CREATE INDEX IF NOT EXISTS Idx_tbl_transaction_module_id ON tbl_transaction ( module_id ); +CREATE INDEX IF NOT EXISTS Idx_deploy_transaction_app_id ON deploy_transaction ( app_id ); -CREATE INDEX IF NOT EXISTS Idx_tbl_transaction_module_lifetime ON tbl_transaction ( module_id, issued_at ); +CREATE INDEX IF NOT EXISTS Idx_deploy_transaction_module_lifetime ON deploy_transaction ( app_id, issued_at ); -CREATE TABLE IF NOT EXISTS tbl_remove_history ( +CREATE TABLE IF NOT EXISTS application_history ( transaction_id varchar(63) NOT NULL, - module_id varchar(127) NOT NULL, + app_id varchar(127) NOT NULL, event varchar(15) NOT NULL, status varchar(15) NOT NULL, issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -50,5 +50,17 @@ CREATE TABLE IF NOT EXISTS tbl_remove_history ( prev_app_config_json text, prev_system_config_json text, retry integer NOT NULL DEFAULT 0, - CONSTRAINT Pk_tbl_remove_history PRIMARY KEY ( transaction_id ) + CONSTRAINT Pk_application_history PRIMARY KEY ( transaction_id ) + ); + + CREATE TABLE IF NOT EXISTS APPLICATION_BACKUP ( + ID uuid NOT NULL, + APP_ID varchar(127) , + STATUS varchar(15) NOT NULL, + DATA_DIR_JSON text, + INSTALLATION_DIR_JSON text, + ERROR_JSON text, + TIME_AUDIT varchar(500) , + SYNC_AUDIT clob(2147483647) , + CONSTRAINT PK_APPLICATION_BACKUP PRIMARY KEY ( ID ) ); diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java b/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java index 7860b99a7..ac18355ca 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java +++ b/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java @@ -1,8 +1,8 @@ package com.nubeiot.edge.installer.mock; import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.ApplicationService; import com.nubeiot.edge.installer.service.InstallerService; -import com.nubeiot.edge.installer.service.ModuleService; import com.nubeiot.edge.installer.service.TransactionService; import lombok.NonNull; @@ -13,13 +13,13 @@ default String api() { return "mock.installer." + this.getClass().getSimpleName(); } - default String rootPath() { - return "/modules"; + default String appPath() { + return "/app"; } - class MockModuleService extends ModuleService implements MockInstallerService { + class MockApplicationService extends ApplicationService implements MockInstallerService { - public MockModuleService(@NonNull InstallerEntityHandler entityHandler) { + public MockApplicationService(@NonNull InstallerEntityHandler entityHandler) { super(entityHandler); } diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java b/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java index 2e0a07ce0..f3745bff9 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java +++ b/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java @@ -10,9 +10,9 @@ import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; import com.nubeiot.edge.installer.loader.ModuleTypeRule; -import com.nubeiot.edge.installer.mock.MockInstallerService.MockModuleService; +import com.nubeiot.edge.installer.mock.MockInstallerService.MockApplicationService; import com.nubeiot.edge.installer.mock.MockInstallerService.MockTransactionService; -import com.nubeiot.edge.installer.service.AppDeployer; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.InstallerService; import lombok.AllArgsConstructor; @@ -23,7 +23,7 @@ @AllArgsConstructor public class MockInstallerVerticle extends InstallerVerticle { - private final AppDeployer appDeployer; + private final AppDeployerDefinition definition; private String configFile = "mock-installer.json"; @Override @@ -38,13 +38,13 @@ public class MockInstallerVerticle extends InstallerVerticle { } @Override - protected @NonNull AppDeployer appDeployer() { - return appDeployer; + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return definition; } @Override protected @NonNull Supplier> services(@NonNull InstallerEntityHandler handler) { - return () -> Stream.of(new MockModuleService(handler), new MockTransactionService(handler)) + return () -> Stream.of(new MockApplicationService(handler), new MockTransactionService(handler)) .collect(Collectors.toSet()); } diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java b/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java index be2971012..ca9b103bc 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java +++ b/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java @@ -15,7 +15,7 @@ public class MockDeploymentService extends AppDeploymentService { @NonNull private final UUID mockDeployId; - MockDeploymentService(@NonNull InstallerEntityHandler entityHandler, @NonNull UUID mockDeployId) { + protected MockDeploymentService(@NonNull InstallerEntityHandler entityHandler, @NonNull UUID mockDeployId) { super(entityHandler); this.mockDeployId = mockDeployId; } diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java b/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java index be8f54caa..6e5d2f0ee 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java +++ b/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java @@ -5,7 +5,7 @@ //TODO extends this for success/failed/timeout case and assert PostDeploymentResult public class MockFinisherService extends AppDeploymentFinisher { - MockFinisherService(InstallerEntityHandler entityHandler) { + protected MockFinisherService(InstallerEntityHandler entityHandler) { super(entityHandler); } diff --git a/core/sql/src/main/java/com/nubeiot/core/sql/SchemaHandler.java b/core/sql/src/main/java/com/nubeiot/core/sql/SchemaHandler.java index f54fc5e57..8625f3b5a 100644 --- a/core/sql/src/main/java/com/nubeiot/core/sql/SchemaHandler.java +++ b/core/sql/src/main/java/com/nubeiot/core/sql/SchemaHandler.java @@ -104,8 +104,8 @@ default boolean isNew(DSLContext dsl) { : migrator().execute(entityHandler); final EventbusClient c = entityHandler.eventClient(); final String address = readinessAddress(entityHandler); - return result.doOnError(t -> c.publish(address, EventMessage.initial(EventAction.NOTIFY_ERROR, - ErrorData.builder().throwable(t).build()))) + return result.doOnError(t -> c.publish(address, EventMessage.error(EventAction.NOTIFY_ERROR, + ErrorData.builder().throwable(t).build()))) .doOnSuccess(msg -> { final JsonObject headers = new JsonObject().put("status", msg.getStatus()) .put("action", msg.getAction()); diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosEntityHandler.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosEntityHandler.java index a9d184b97..5924cfa04 100644 --- a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosEntityHandler.java +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosEntityHandler.java @@ -10,8 +10,8 @@ import com.nubeiot.edge.installer.InstallerConfig; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; public final class EdgeBiosEntityHandler extends InstallerEntityHandler { @@ -19,8 +19,8 @@ protected EdgeBiosEntityHandler(Configuration configuration, Vertx vertx) { super(configuration, vertx); } - protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule tblModule, AppConfig appConfig) { - if (String.format("%s:%s", "com.nubeiot.edge.module", "installer").equals(tblModule.getServiceId())) { + protected AppConfig transformAppConfig(RepositoryConfig repoConfig, IApplication application, AppConfig appConfig) { + if (String.format("%s:%s", "com.nubeiot.edge.module", "installer").equals(application.getAppId())) { InstallerConfig installerConfig = new InstallerConfig(); installerConfig.setRepoConfig(repoConfig); return IConfig.merge(new JsonObject().put(installerConfig.key(), installerConfig.toJson()), appConfig, @@ -29,7 +29,7 @@ protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule t return appConfig; } - protected TblModule decorateModule(TblModule m) { + protected Application decorateModule(Application m) { return super.decorateModule(m).setPublishedBy("NubeIO"); } diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosVerticle.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosVerticle.java index 4c89a78a2..3378c0c41 100644 --- a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosVerticle.java +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosVerticle.java @@ -7,7 +7,7 @@ import com.nubeiot.edge.installer.InstallerEntityHandler; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleTypeRule; -import com.nubeiot.edge.installer.service.AppDeployer; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.InstallerService; import com.nubeiot.eventbus.edge.installer.InstallerEventModel; @@ -26,9 +26,10 @@ protected Supplier getModuleRuleProvider() { } @Override - protected @NonNull AppDeployer appDeployer() { - return AppDeployer.create(InstallerEventModel.BIOS_DEPLOYMENT, InstallerEventModel.BIOS_DEPLOYMENT_TRACKER, - InstallerEventModel.BIOS_DEPLOYMENT_FINISHER); + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return AppDeployerDefinition.create(InstallerEventModel.BIOS_DEPLOYMENT, + InstallerEventModel.BIOS_DEPLOYMENT_TRACKER, + InstallerEventModel.BIOS_DEPLOYMENT_FINISHER); } @Override diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosApplicationService.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosApplicationService.java new file mode 100644 index 000000000..6a4c07780 --- /dev/null +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosApplicationService.java @@ -0,0 +1,12 @@ +package com.nubeiot.edge.bios.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.ApplicationService; + +public final class BiosApplicationService extends ApplicationService implements BiosInstallerService { + + public BiosApplicationService(InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosBackupByAppService.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosBackupByAppService.java new file mode 100644 index 000000000..a415b600d --- /dev/null +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosBackupByAppService.java @@ -0,0 +1,14 @@ +package com.nubeiot.edge.bios.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.BackupByAppService; + +import lombok.NonNull; + +public final class BiosBackupByAppService extends BackupByAppService implements BiosInstallerService { + + protected BiosBackupByAppService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosInstallerService.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosInstallerService.java index 20bf14208..ddb478a5c 100644 --- a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosInstallerService.java +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosInstallerService.java @@ -8,8 +8,8 @@ default String api() { return "bios.installer." + this.getClass().getSimpleName(); } - default String rootPath() { - return "/modules"; + default String appPath() { + return "/app"; } } diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosModuleService.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosModuleService.java deleted file mode 100644 index c3aceb54d..000000000 --- a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosModuleService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.nubeiot.edge.bios.service; - -import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.service.ModuleService; - -public final class BiosModuleService extends ModuleService implements BiosInstallerService { - - public BiosModuleService(InstallerEntityHandler entityHandler) { - super(entityHandler); - } - -} diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosTransactionByAppService.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosTransactionByAppService.java new file mode 100644 index 000000000..a15257fbf --- /dev/null +++ b/edge/bios/src/main/java/com/nubeiot/edge/bios/service/BiosTransactionByAppService.java @@ -0,0 +1,14 @@ +package com.nubeiot.edge.bios.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.TransactionByAppService; + +import lombok.NonNull; + +public final class BiosTransactionByAppService extends TransactionByAppService implements BiosInstallerService { + + public BiosTransactionByAppService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/BaseInstallerVerticleTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/BaseInstallerVerticleTest.java index ebfd88837..5d6312767 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/BaseInstallerVerticleTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/BaseInstallerVerticleTest.java @@ -36,10 +36,10 @@ import com.nubeiot.core.event.EventPattern; import com.nubeiot.core.sql.SqlConfig; import com.nubeiot.core.statemachine.StateMachine; -import com.nubeiot.edge.bios.service.BiosModuleService; +import com.nubeiot.edge.bios.service.BiosApplicationService; import com.nubeiot.edge.installer.InstallerVerticle; -import com.nubeiot.edge.installer.model.tables.daos.TblModuleDao; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.pojos.Application; import lombok.NonNull; @@ -113,9 +113,9 @@ protected NubeConfig getNubeConfig() { return nubeConfig; } - protected void insertModule(TestContext context, TblModule module) { + protected void insertModule(TestContext context, Application module) { Async async = context.async(1); - installerVerticle.getEntityHandler().moduleDao().insert(module).subscribe(result -> { + installerVerticle.getEntityHandler().applicationDao().insert(module).subscribe(result -> { System.out.println("Insert module successfully!"); TestHelper.testComplete(async); }, error -> { @@ -143,8 +143,9 @@ protected void testingDBUpdated(TestContext context, State expectedModuleState, private void assertTransaction(TestContext context, Status expectedTransactionStatus, Async async, CountDownLatch latch) { - installerVerticle.getEntityHandler().transDao() - .findManyByModuleId(Collections.singletonList(BaseInstallerVerticleTest.MODULE_ID)) + installerVerticle.getEntityHandler() + .transDao() + .findManyByAppId(Collections.singletonList(BaseInstallerVerticleTest.MODULE_ID)) .subscribe(result -> { context.assertNotNull(result); context.assertFalse(result.isEmpty()); @@ -164,16 +165,17 @@ private void assertTransaction(TestContext context, Status expectedTransactionSt private void assertModule(TestContext context, State expectedModuleState, JsonObject expectedConfig, Async async, CountDownLatch latch) { - installerVerticle.getEntityHandler().moduleDao() + installerVerticle.getEntityHandler() + .applicationDao() .findOneById(BaseInstallerVerticleTest.MODULE_ID) .subscribe(result -> { - TblModule tblModule = result.orElse(null); - context.assertNotNull(tblModule); - if (tblModule.getState() != State.PENDING) { + Application application = result.orElse(null); + context.assertNotNull(application); + if (application.getState() != State.PENDING) { latch.countDown(); System.out.println("Ready. Testing module"); - context.assertEquals(tblModule.getState(), expectedModuleState); - JsonObject actualConfig = IConfig.from(tblModule.getAppConfig(), AppConfig.class) + context.assertEquals(application.getState(), expectedModuleState); + JsonObject actualConfig = IConfig.from(application.getAppConfig(), AppConfig.class) .toJson(); JsonHelper.assertJson(context, async, expectedConfig, actualConfig, JSONCompareMode.STRICT); @@ -188,21 +190,21 @@ private void assertModule(TestContext context, State expectedModuleState, JsonOb void executeThenAssert(EventAction action, TestContext context, JsonObject body, Handler handler) { installerVerticle.getEventbusClient() - .fire(DeliveryEvent.from(BiosModuleService.class.getName(), EventPattern.REQUEST_RESPONSE, + .fire(DeliveryEvent.from(BiosApplicationService.class.getName(), EventPattern.REQUEST_RESPONSE, action, RequestData.builder().body(body).build().toJson()), EventbusHelper.replyAsserter(context, handler)); } protected void assertModuleState(TestContext context, Async async, State expectedState, String moduleId) { - final TblModuleDao moduleDao = this.installerVerticle.getEntityHandler().moduleDao(); + final ApplicationDao moduleDao = this.installerVerticle.getEntityHandler().applicationDao(); CountDownLatch latch = new CountDownLatch(1); long timer = this.vertx.setPeriodic(1000, event -> moduleDao.findOneById(moduleId).subscribe(result -> { - TblModule tblModule = result.orElse(null); - context.assertNotNull(tblModule); - if (tblModule.getState() != State.PENDING) { + Application application = result.orElse(null); + context.assertNotNull(application); + if (application.getState() != State.PENDING) { System.out.println("Checking state of " + moduleId); if (Objects.nonNull(expectedState)) { - context.assertEquals(tblModule.getState(), expectedState); + context.assertEquals(application.getState(), expectedState); } latch.countDown(); TestHelper.testComplete(async); diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeleteTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeleteTest.java index a94a2e4bd..5ecdac061 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeleteTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeleteTest.java @@ -25,10 +25,10 @@ import com.nubeiot.core.exceptions.NubeException.ErrorCode; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.bios.loader.DeploymentAsserter; -import com.nubeiot.edge.bios.service.BiosModuleService; +import com.nubeiot.edge.bios.service.BiosApplicationService; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; @Ignore public class HandlerDeleteTest extends BaseInstallerVerticleTest { @@ -36,14 +36,14 @@ public class HandlerDeleteTest extends BaseInstallerVerticleTest { @Before public void before(TestContext context) { super.before(context); - this.insertModule(context, new TblModule().setServiceId(MODULE_ID) - .setServiceType(ModuleType.JAVA) - .setServiceName(SERVICE_NAME) - .setState(State.ENABLED) - .setVersion(VERSION) - .setSystemConfig(APP_SYSTEM_CONFIG) - .setAppConfig(APP_CONFIG) - .setModifiedAt(DateTimes.now())); + this.insertModule(context, new Application().setAppId(MODULE_ID) + .setServiceType(ModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setAppConfig(APP_CONFIG) + .setModifiedAt(DateTimes.now())); } @Override @@ -56,24 +56,24 @@ public void test_delete_should_success(TestContext context) { JsonObject body = new JsonObject().put("service_id", MODULE_ID); Async async = context.async(); installerVerticle.getEventbusClient() - .fire(DeliveryEvent.from(BiosModuleService.class.getName(), EventPattern.REQUEST_RESPONSE, + .fire(DeliveryEvent.from(BiosApplicationService.class.getName(), EventPattern.REQUEST_RESPONSE, EventAction.REMOVE, RequestData.builder().body(body).build().toJson()), EventbusHelper.replyAsserter(context, resp -> { - System.out.println(resp); - context.assertEquals(resp.getString("status"), Status.SUCCESS.name()); - TestHelper.testComplete(async); - })); + System.out.println(resp); + context.assertEquals(resp.getString("status"), Status.SUCCESS.name()); + TestHelper.testComplete(async); + })); CountDownLatch latch = new CountDownLatch(2); Async async2 = context.async(2); //Event module is deployed/updated successfully, we still have a gap for DB update. long timer = this.vertx.setPeriodic(1000, event -> { - installerVerticle.getEntityHandler().moduleDao().findOneById(GROUP_ID).subscribe(result -> { - TblModule tblModule = result.orElse(null); - if (Objects.nonNull(tblModule) && tblModule.getState() != State.PENDING) { + installerVerticle.getEntityHandler().applicationDao().findOneById(GROUP_ID).subscribe(result -> { + Application application = result.orElse(null); + if (Objects.nonNull(application) && application.getState() != State.PENDING) { return; } - context.assertNull(tblModule); + context.assertNull(application); TestHelper.testComplete(async2); latch.countDown(); }, error -> { @@ -81,19 +81,20 @@ public void test_delete_should_success(TestContext context) { context.fail(error); TestHelper.testComplete(async2); }); - installerVerticle.getEntityHandler().transDao() - .findManyByModuleId(Collections.singletonList(MODULE_ID)) + installerVerticle.getEntityHandler() + .transDao() + .findManyByAppId(Collections.singletonList(MODULE_ID)) .subscribe(result -> { - if (!Objects.nonNull(result) || result.isEmpty() || - result.get(0).getStatus() != Status.WIP) { - TestHelper.testComplete(async2); - latch.countDown(); - } - }, error -> { - latch.countDown(); - context.fail(error); - TestHelper.testComplete(async2); - }); + if (!Objects.nonNull(result) || result.isEmpty() || + result.get(0).getStatus() != Status.WIP) { + TestHelper.testComplete(async2); + latch.countDown(); + } + }, error -> { + latch.countDown(); + context.fail(error); + TestHelper.testComplete(async2); + }); }); stopTimer(context, latch, timer); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeployFailedTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeployFailedTest.java index 39b3f859b..2261d7595 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeployFailedTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerDeployFailedTest.java @@ -13,7 +13,7 @@ import com.nubeiot.edge.bios.loader.DeploymentAsserter; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; @Ignore public class HandlerDeployFailedTest extends BaseInstallerVerticleTest { @@ -81,14 +81,14 @@ public void test_delete_when_deploy_failed(TestContext context) { } private void createService(TestContext context) { - this.insertModule(context, new TblModule().setServiceId(MODULE_ID) - .setServiceType(ModuleType.JAVA) - .setServiceName(SERVICE_NAME) - .setState(State.ENABLED) - .setVersion(VERSION) - .setAppConfig(APP_CONFIG) - .setSystemConfig(APP_SYSTEM_CONFIG) - .setModifiedAt(DateTimes.now())); + this.insertModule(context, new Application().setAppId(MODULE_ID) + .setServiceType(ModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setAppConfig(APP_CONFIG) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setModifiedAt(DateTimes.now())); } } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerUpdateAndPatchTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerUpdateAndPatchTest.java index 15d0e0e04..fc6ca3f09 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerUpdateAndPatchTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/HandlerUpdateAndPatchTest.java @@ -15,7 +15,7 @@ import com.nubeiot.edge.bios.loader.DeploymentAsserter; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; @Ignore public class HandlerUpdateAndPatchTest extends BaseInstallerVerticleTest { @@ -23,14 +23,14 @@ public class HandlerUpdateAndPatchTest extends BaseInstallerVerticleTest { @Before public void before(TestContext context) { super.before(context); - this.insertModule(context, new TblModule().setServiceId(MODULE_ID) - .setServiceType(ModuleType.JAVA) - .setServiceName(SERVICE_NAME) - .setState(State.ENABLED) - .setVersion(VERSION) - .setAppConfig(APP_CONFIG) - .setSystemConfig(APP_SYSTEM_CONFIG) - .setModifiedAt(DateTimes.now())); + this.insertModule(context, new Application().setAppId(MODULE_ID) + .setServiceType(ModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setAppConfig(APP_CONFIG) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setModifiedAt(DateTimes.now())); } @Override diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/ServiceNameDuplicationTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/ServiceNameDuplicationTest.java index ab254853f..51d6d849e 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/ServiceNameDuplicationTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/ServiceNameDuplicationTest.java @@ -14,7 +14,7 @@ import com.nubeiot.edge.bios.loader.DeploymentAsserter; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; @Ignore public class ServiceNameDuplicationTest extends BaseInstallerVerticleTest { @@ -22,14 +22,14 @@ public class ServiceNameDuplicationTest extends BaseInstallerVerticleTest { @Before public void before(TestContext context) { super.before(context); - this.insertModule(context, new TblModule().setServiceId(MODULE_ID) - .setServiceType(ModuleType.JAVA) - .setServiceName(SERVICE_NAME) - .setState(State.ENABLED) - .setVersion(VERSION) - .setSystemConfig(APP_SYSTEM_CONFIG) - .setAppConfig(APP_CONFIG) - .setModifiedAt(DateTimes.now())); + this.insertModule(context, new Application().setAppId(MODULE_ID) + .setServiceType(ModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setAppConfig(APP_CONFIG) + .setModifiedAt(DateTimes.now())); } @Override diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/DeploymentAsserter.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/DeploymentAsserter.java index 5cd5697fb..bf45d7933 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/DeploymentAsserter.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/DeploymentAsserter.java @@ -13,7 +13,7 @@ import com.nubeiot.core.enums.Status; import com.nubeiot.core.event.EventAction; import com.nubeiot.core.event.EventMessage; -import com.nubeiot.edge.bios.service.BiosModuleService; +import com.nubeiot.edge.bios.service.BiosApplicationService; import com.nubeiot.edge.bios.service.BiosTransactionService; import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; @@ -34,7 +34,7 @@ static DeploymentAsserter init(Vertx vertx, TestContext context) { RequestData.builder().body(transactionBody).build()); final Async async = context.async(2); - vertx.eventBus().send(BiosModuleService.class.getName(), serviceMessage.toJson(), result -> { + vertx.eventBus().send(BiosApplicationService.class.getName(), serviceMessage.toJson(), result -> { System.out.println("Asserting module"); JsonObject body = (JsonObject) result.result().body(); context.assertEquals(body.getString("status"), Status.SUCCESS.name()); diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/EnabledModuleInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/EnabledModuleInitData.java index d7e6bcdee..92a6a1b0a 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/EnabledModuleInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/EnabledModuleInitData.java @@ -9,7 +9,7 @@ import com.nubeiot.core.enums.State; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; public class EnabledModuleInitData extends MockInitDataEntityHandler { @@ -19,15 +19,15 @@ protected EnabledModuleInitData(Configuration configuration, Vertx vertx) { @Override protected Single initModules() { - return tblModuleDao.insert(new TblModule().setServiceId("enabled-service") - .setServiceName("service0") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.ENABLED) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + return applicationDao.insert(new Application().setAppId("enabled-service") + .setServiceName("service0") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.ENABLED) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); } } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/InvalidModulesInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/InvalidModulesInitData.java index a0b2e0878..6e55bb5a2 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/InvalidModulesInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/InvalidModulesInitData.java @@ -15,8 +15,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class InvalidModulesInitData extends MockInitDataEntityHandler { @@ -26,111 +26,112 @@ protected InvalidModulesInitData(Configuration configuration, Vertx vertx) { @Override protected Single initModules() { - final TblModule service5 = new TblModule().setServiceId( + final Application service5 = new Application().setAppId( "pending-service-with-transaction-is-wip-prestate-action-is-update-disabled") - .setServiceName("service5") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject()); - Single insert05 = tblModuleDao.insert(service5); + .setServiceName("service5") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject()); + Single insert05 = applicationDao.insert(service5); Single insertTransaction05 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId(service5.getServiceId()) - .setStatus(Status.WIP) - .setEvent(EventAction.UPDATE) - .setModifiedAt(DateTimes.now()) - .setPrevMetadata(new JsonObject( - "{\"service_id\": \"pending-service-with-transaction-is-wip-prestate-action-is" + - "-patch-disabled\",\"service_name\": \"service6\",\"service_type\": \"JAVA\"," + - "\"version\": \"1.0.0\",\"published_by\": null,\"state\": \"DISABLED\"," + - "\"created_at\": \"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\": \"2019-05-02T09:15:37.230Z\",\"deploy_id\": null," + - "\"deploy_config\": {},\"deploy_location\": null }"))); - - final TblModule service6 = new TblModule().setServiceId( + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId(service5.getAppId()) + .setStatus(Status.WIP) + .setEvent(EventAction.UPDATE) + .setModifiedAt(DateTimes.now()) + .setPrevMetadata(new JsonObject( + "{\"service_id\": \"pending-service-with-transaction-is-wip-prestate-action-is" + + "-patch-disabled\",\"service_name\": \"service6\",\"service_type\": \"JAVA\"," + + "\"version\": \"1.0.0\",\"published_by\": null,\"state\": \"DISABLED\"," + + "\"created_at\": \"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\": \"2019-05-02T09:15:37.230Z\",\"deploy_id\": null," + + "\"deploy_config\": {},\"deploy_location\": null }"))); + + final Application service6 = new Application().setAppId( "pending-service-with-transaction-is-wip-prestate-action-is-patch-disabled") - .setServiceName("service6") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject()); - Single insert06 = tblModuleDao.insert(service6); + .setServiceName("service6") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject()); + Single insert06 = applicationDao.insert(service6); Single insertTransaction06 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId(service6.getServiceId()) - .setStatus(Status.WIP) - .setEvent(EventAction.PATCH) - .setModifiedAt(DateTimes.now()) - .setPrevMetadata(new JsonObject( - "{\"service_id\":\"pending-service-with-transaction-is-wip-prestate-action-is" + - "-update-disabled\",\"service_name" + "\":\"service5\",\"service_type\":\"JAVA\"," + - "\"version\":\"1.0.0\"," + "\"published_by\":null," + "\"state\":\"DISABLED\"," + - "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + - "\"deploy_config\":{}," + "\"deploy_location\":null}\t "))); - - Single insert07 = tblModuleDao.insert(new TblModule().setServiceId("disabled-module") - .setServiceName("service7") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.DISABLED) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setAppConfig(new JsonObject()) - .setSystemConfig(new JsonObject())); - - Single insert09 = tblModuleDao.insert( - new TblModule().setServiceId("pending_module_with_two_transactions_invalid") - .setServiceName("service9") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId(service6.getAppId()) + .setStatus(Status.WIP) + .setEvent(EventAction.PATCH) + .setModifiedAt(DateTimes.now()) + .setPrevMetadata(new JsonObject( + "{\"service_id\":\"pending-service-with-transaction-is-wip-prestate-action-is" + + "-update-disabled\",\"service_name" + + "\":\"service5\",\"service_type\":\"JAVA\"," + "\"version\":\"1.0.0\"," + + "\"published_by\":null," + "\"state\":\"DISABLED\"," + + "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + + "\"deploy_config\":{}," + "\"deploy_location\":null}\t "))); + + Single insert07 = applicationDao.insert(new Application().setAppId("disabled-module") + .setServiceName("service7") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.DISABLED) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setAppConfig(new JsonObject()) + .setSystemConfig(new JsonObject())); + + Single insert09 = applicationDao.insert( + new Application().setAppId("pending_module_with_two_transactions_invalid") + .setServiceName("service9") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction09_1 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending_module_with_two_transactions_invalid") - .setStatus(Status.WIP) - .setEvent(EventAction.CREATE) - .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 25, 0, ZoneOffset.UTC))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending_module_with_two_transactions_invalid") + .setStatus(Status.WIP) + .setEvent(EventAction.CREATE) + .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 25, 0, ZoneOffset.UTC))); Single insertTransaction09_2 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending_module_with_two_transactions_invalid") - .setStatus(Status.WIP) - .setEvent(EventAction.PATCH) - .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC)) - .setPrevMetadata(new JsonObject( - "{\"service_id\":\"pending_module_with_two_transactions_invalid\"," + - "\"service_name\":\"service9\",\"service_type\":\"JAVA\"," + - "\"version\":\"1.0.0\",\"published_by\":null,\"state\":\"DISABLED\"," + - "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + - "\"deploy_config\":{}," + "\"deploy_location\":null}"))); - - Single insert10 = tblModuleDao.insert(new TblModule().setServiceId("pending-but-failed-module") - .setServiceName("service10") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now())); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending_module_with_two_transactions_invalid") + .setStatus(Status.WIP) + .setEvent(EventAction.PATCH) + .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC)) + .setPrevMetadata(new JsonObject( + "{\"service_id\":\"pending_module_with_two_transactions_invalid\"," + + "\"service_name\":\"service9\",\"service_type\":\"JAVA\"," + + "\"version\":\"1.0.0\",\"published_by\":null,\"state\":\"DISABLED\"," + + "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + + "\"deploy_config\":{}," + "\"deploy_location\":null}"))); + + Single insert10 = applicationDao.insert(new Application().setAppId("pending-but-failed-module") + .setServiceName("service10") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now())); Single insertTransaction10 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending-but-failed-module") - .setStatus(Status.FAILED) - .setEvent(EventAction.CREATE) - .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending-but-failed-module") + .setStatus(Status.FAILED) + .setEvent(EventAction.CREATE) + .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC))); final Single insertModules = Single.zip(insert05, insert06, insert07, insert09, insert10, (r1, r2, r3, r4, r5) -> r1 + r2 + r3 + r4 + r5); diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/MockInitDataEntityHandler.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/MockInitDataEntityHandler.java index 38d29a51e..cf15c1dee 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/MockInitDataEntityHandler.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/MockInitDataEntityHandler.java @@ -8,19 +8,19 @@ import com.nubeiot.core.NubeConfig.AppConfig; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.tables.daos.TblModuleDao; -import com.nubeiot.edge.installer.model.tables.daos.TblTransactionDao; -import com.nubeiot.edge.installer.model.tables.interfaces.ITblModule; +import com.nubeiot.edge.installer.model.tables.daos.ApplicationDao; +import com.nubeiot.edge.installer.model.tables.daos.DeployTransactionDao; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; abstract class MockInitDataEntityHandler extends InstallerEntityHandler { - final TblModuleDao tblModuleDao; - final TblTransactionDao tblTransactionDao; + final ApplicationDao applicationDao; + final DeployTransactionDao tblTransactionDao; MockInitDataEntityHandler(Configuration configuration, Vertx vertx) { super(configuration, vertx); - this.tblModuleDao = dao(TblModuleDao.class); - this.tblTransactionDao = dao(TblTransactionDao.class); + this.applicationDao = applicationDao(); + this.tblTransactionDao = transDao(); } // @Override @@ -32,7 +32,7 @@ abstract class MockInitDataEntityHandler extends InstallerEntityHandler { // } @Override - protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule tblModule, AppConfig appConfig) { + protected AppConfig transformAppConfig(RepositoryConfig repoConfig, IApplication tblModule, AppConfig appConfig) { return appConfig; } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithCreateActionInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithCreateActionInitData.java index 0494f43e9..926783b91 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithCreateActionInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithCreateActionInitData.java @@ -13,8 +13,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class PendingModuleWithCreateActionInitData extends MockInitDataEntityHandler { @@ -24,20 +24,22 @@ protected PendingModuleWithCreateActionInitData(Configuration configuration, Ver @Override protected Single initModules() { - Single insert02 = tblModuleDao.insert( - new TblModule().setServiceId("pending-service-with-transaction-is-wip-prestate-action-is-create") - .setServiceName("service2") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + Single insert02 = applicationDao.insert( + new Application().setAppId("pending-service-with-transaction-is-wip-prestate-action-is-create") + .setServiceName("service2") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction02 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending-service-with-transaction-is-wip-prestate-action-is-create") - .setStatus(Status.WIP).setEvent(EventAction.CREATE).setModifiedAt(DateTimes.now())); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending-service-with-transaction-is-wip-prestate-action-is-create") + .setStatus(Status.WIP) + .setEvent(EventAction.CREATE) + .setModifiedAt(DateTimes.now())); return Single.zip(insert02, insertTransaction02, Integer::sum); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithInitActionInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithInitActionInitData.java index 96036f49e..14036c491 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithInitActionInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithInitActionInitData.java @@ -13,8 +13,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class PendingModuleWithInitActionInitData extends MockInitDataEntityHandler { @@ -24,20 +24,22 @@ protected PendingModuleWithInitActionInitData(Configuration configuration, Vertx @Override protected Single initModules() { - Single insert01 = tblModuleDao.insert( - new TblModule().setServiceId("pending-service-with-transaction-is-wip-prestate-action-is-init") - .setServiceName("service1") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + Single insert01 = applicationDao.insert( + new Application().setAppId("pending-service-with-transaction-is-wip-prestate-action-is-init") + .setServiceName("service1") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction01 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending-service-with-transaction-is-wip-prestate-action-is-init") - .setStatus(Status.WIP).setEvent(EventAction.INIT).setModifiedAt(DateTimes.now())); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending-service-with-transaction-is-wip-prestate-action-is-init") + .setStatus(Status.WIP) + .setEvent(EventAction.INIT) + .setModifiedAt(DateTimes.now())); return Single.zip(insert01, insertTransaction01, Integer::sum); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithPatchActionInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithPatchActionInitData.java index 7f4109cc7..322e0e27a 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithPatchActionInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithPatchActionInitData.java @@ -13,8 +13,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class PendingModuleWithPatchActionInitData extends MockInitDataEntityHandler { @@ -24,31 +24,31 @@ protected PendingModuleWithPatchActionInitData(Configuration configuration, Vert @Override protected Single initModules() { - Single insert04 = tblModuleDao.insert( - new TblModule().setServiceId("pending-service-with-transaction-is-wip-prestate-action-is-patch") - .setServiceName("service4") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + Single insert04 = applicationDao.insert( + new Application().setAppId("pending-service-with-transaction-is-wip-prestate-action-is-patch") + .setServiceName("service4") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction04 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending-service-with-transaction-is-wip-prestate-action-is-patch") - .setStatus(Status.WIP) - .setEvent(EventAction.PATCH) - .setModifiedAt(DateTimes.now()) - .setPrevMetadata(new JsonObject( - "{\"service_id\":\"pending-service-with-transaction-is-wip" + - "-prestate-action-is-patch\"," + - "\"service_name\":\"service4\",\"service_type\":\"JAVA\"," + - "\"version\":\"1.0.0\",\"published_by\":null," + "\"state\":\"PENDING\"," + - "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"deploy_id\":null,\"deploy_config\":{}," + "\"deploy_location\":null}\t"))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending-service-with-transaction-is-wip-prestate-action-is-patch") + .setStatus(Status.WIP) + .setEvent(EventAction.PATCH) + .setModifiedAt(DateTimes.now()) + .setPrevMetadata(new JsonObject( + "{\"service_id\":\"pending-service-with-transaction-is-wip" + + "-prestate-action-is-patch\"," + + "\"service_name\":\"service4\",\"service_type\":\"JAVA\"," + + "\"version\":\"1.0.0\",\"published_by\":null," + "\"state\":\"PENDING\"," + + "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"deploy_id\":null,\"deploy_config\":{}," + "\"deploy_location\":null}\t"))); return Single.zip(insert04, insertTransaction04, Integer::sum); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithTwoTransactionsInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithTwoTransactionsInitData.java index 78ab9d5e2..67e5fa22a 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithTwoTransactionsInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithTwoTransactionsInitData.java @@ -15,8 +15,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class PendingModuleWithTwoTransactionsInitData extends MockInitDataEntityHandler { @@ -26,36 +26,36 @@ protected PendingModuleWithTwoTransactionsInitData(Configuration configuration, @Override protected Single initModules() { - Single insert08 = tblModuleDao.insert( - new TblModule().setServiceId("pending_module_with_two_transactions") - .setServiceName("service8") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + Single insert08 = applicationDao.insert( + new Application().setAppId("pending_module_with_two_transactions") + .setServiceName("service8") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction08_1 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending_module_with_two_transactions") - .setStatus(Status.WIP) - .setEvent(EventAction.PATCH) - .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 25, 0, ZoneOffset.UTC)) - .setPrevMetadata(new JsonObject( - "{\"service_id" + "\":\"pending_module_with_two_transactions\"," + - "\"service_name" + "\":\"service5" + "\",\"service_type\":\"JAVA\"," + - "\"version\":\"1.0.0\"," + "\"published_by\":null," + "\"state\":\"DISABLED\"," + - "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + - "\"deploy_config\":{},\"deploy_location\":null}\t "))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending_module_with_two_transactions") + .setStatus(Status.WIP) + .setEvent(EventAction.PATCH) + .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 25, 0, ZoneOffset.UTC)) + .setPrevMetadata(new JsonObject( + "{\"service_id" + "\":\"pending_module_with_two_transactions\"," + + "\"service_name" + "\":\"service5" + "\",\"service_type\":\"JAVA\"," + + "\"version\":\"1.0.0\"," + "\"published_by\":null," + "\"state\":\"DISABLED\"," + + "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\":\"2019-05-02T09:15:37.230Z\",\"deploy_id\":null," + + "\"deploy_config\":{},\"deploy_location\":null}\t "))); Single insertTransaction08_2 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending_module_with_two_transactions") - .setStatus(Status.WIP) - .setEvent(EventAction.CREATE) - .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending_module_with_two_transactions") + .setStatus(Status.WIP) + .setEvent(EventAction.CREATE) + .setModifiedAt(OffsetDateTime.of(2019, 5, 3, 12, 20, 30, 0, ZoneOffset.UTC))); return Single.zip(insert08, insertTransaction08_1, insertTransaction08_2, (r1, r2, r3) -> r1 + r2 + r3); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithUpdateActionInitData.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithUpdateActionInitData.java index 27e8b18c7..e943c3d03 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithUpdateActionInitData.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/startupmodules/handler/PendingModuleWithUpdateActionInitData.java @@ -13,8 +13,8 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; -import com.nubeiot.edge.installer.model.tables.pojos.TblTransaction; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.tables.pojos.DeployTransaction; public class PendingModuleWithUpdateActionInitData extends MockInitDataEntityHandler { @@ -24,31 +24,31 @@ protected PendingModuleWithUpdateActionInitData(Configuration configuration, Ver @Override protected Single initModules() { - Single insert03 = tblModuleDao.insert( - new TblModule().setServiceId("pending-service-with-transaction-is-wip-prestate-action-is-update") - .setServiceName("service3") - .setServiceType(ModuleType.JAVA) - .setVersion("1.0.0") - .setState(State.PENDING) - .setCreatedAt(DateTimes.now()) - .setModifiedAt(DateTimes.now()) - .setSystemConfig(new JsonObject()) - .setAppConfig(new JsonObject())); + Single insert03 = applicationDao.insert( + new Application().setAppId("pending-service-with-transaction-is-wip-prestate-action-is-update") + .setServiceName("service3") + .setServiceType(ModuleType.JAVA) + .setVersion("1.0.0") + .setState(State.PENDING) + .setCreatedAt(DateTimes.now()) + .setModifiedAt(DateTimes.now()) + .setSystemConfig(new JsonObject()) + .setAppConfig(new JsonObject())); Single insertTransaction03 = tblTransactionDao.insert( - new TblTransaction().setTransactionId(UUID.randomUUID().toString()) - .setModuleId("pending-service-with-transaction-is-wip-prestate-action-is-update") - .setStatus(Status.WIP) - .setEvent(EventAction.UPDATE) - .setModifiedAt(DateTimes.now()) - .setPrevMetadata(new JsonObject( - "{\"service_id\":\"pending-service-with-transaction-is-wip" + - "-prestate-action-is-update\"," + - "\"service_name\":\"service3\",\"service_type\":\"JAVA\"," + - "\"version\":\"1.0.0\",\"published_by\":null," + "\"state\":\"PENDING\"," + - "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"modified_at\":\"2019-05-02T09:15:37.230Z\"," + - "\"deploy_id\":null,\"deploy_config\":{}," + "\"deploy_location\":null}\t"))); + new DeployTransaction().setTransactionId(UUID.randomUUID().toString()) + .setAppId("pending-service-with-transaction-is-wip-prestate-action-is-update") + .setStatus(Status.WIP) + .setEvent(EventAction.UPDATE) + .setModifiedAt(DateTimes.now()) + .setPrevMetadata(new JsonObject( + "{\"service_id\":\"pending-service-with-transaction-is-wip" + + "-prestate-action-is-update\"," + + "\"service_name\":\"service3\",\"service_type\":\"JAVA\"," + + "\"version\":\"1.0.0\",\"published_by\":null," + "\"state\":\"PENDING\"," + + "\"created_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"modified_at\":\"2019-05-02T09:15:37.230Z\"," + + "\"deploy_id\":null,\"deploy_config\":{}," + "\"deploy_location\":null}\t"))); return Single.zip(insert03, insertTransaction03, Integer::sum); } diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/timeout/HandlerTimeoutTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/timeout/HandlerTimeoutTest.java index 69fb7cc13..b485b8fe7 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/timeout/HandlerTimeoutTest.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/timeout/HandlerTimeoutTest.java @@ -24,7 +24,7 @@ import com.nubeiot.edge.bios.BaseInstallerVerticleTest; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.tables.pojos.TblModule; +import com.nubeiot.edge.installer.model.tables.pojos.Application; import com.nubeiot.eventbus.edge.installer.InstallerEventModel; @Ignore @@ -33,14 +33,14 @@ public class HandlerTimeoutTest extends BaseInstallerVerticleTest { @Before public void before(TestContext context) { super.before(context); - this.insertModule(context, new TblModule().setServiceId(MODULE_ID) - .setServiceType(ModuleType.JAVA) - .setServiceName(SERVICE_NAME) - .setState(State.ENABLED) - .setVersion(VERSION) - .setAppConfig(APP_CONFIG) - .setSystemConfig(APP_SYSTEM_CONFIG) - .setModifiedAt(DateTimes.now())); + this.insertModule(context, new Application().setAppId(MODULE_ID) + .setServiceType(ModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setAppConfig(APP_CONFIG) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setModifiedAt(DateTimes.now())); } @Override diff --git a/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/AbstractBACnetVerticle.java b/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/AbstractBACnetVerticle.java index 804af26fe..2439cc426 100644 --- a/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/AbstractBACnetVerticle.java +++ b/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/AbstractBACnetVerticle.java @@ -66,8 +66,8 @@ protected void successHandler(@NonNull C config) { private void readinessHandler(@NonNull C config, JsonObject d, Throwable e) { final EventMessage msg = Objects.nonNull(e) - ? EventMessage.initial(EventAction.NOTIFY_ERROR, - ErrorData.builder().throwable(e).build()) + ? EventMessage.error(EventAction.NOTIFY_ERROR, + ErrorData.builder().throwable(e).build()) : EventMessage.initial(EventAction.NOTIFY, RequestData.builder().body(d).build()); getEventbusClient().publish(config.getReadinessAddress(), msg); } diff --git a/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/BACnetDevice.java b/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/BACnetDevice.java index 768052139..0a87c445a 100644 --- a/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/BACnetDevice.java +++ b/edge/connector/bacnet/base/src/main/java/com/nubeiot/edge/connector/bacnet/BACnetDevice.java @@ -147,8 +147,8 @@ private EventMessage createErrorDiscoverMsg(@NonNull Throwable t) { .localDevice(metadata) .build() .toJson(); - return EventMessage.initial(EventAction.NOTIFY_ERROR, - ErrorData.builder().throwable(t).extraInfo(extraInfo).build()); + return EventMessage.error(EventAction.NOTIFY_ERROR, + ErrorData.builder().throwable(t).extraInfo(extraInfo).build()); } } diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/EdgeServiceInstallerVerticle.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/EdgeServiceInstallerVerticle.java index c5819c4b1..df0259382 100644 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/EdgeServiceInstallerVerticle.java +++ b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/EdgeServiceInstallerVerticle.java @@ -6,7 +6,7 @@ import com.nubeiot.edge.installer.InstallerEntityHandler; import com.nubeiot.edge.installer.InstallerVerticle; import com.nubeiot.edge.installer.loader.ModuleTypeRule; -import com.nubeiot.edge.installer.service.AppDeployer; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.InstallerService; import com.nubeiot.edge.module.installer.service.EdgeInstallerService; import com.nubeiot.eventbus.edge.installer.InstallerEventModel; @@ -26,10 +26,10 @@ protected Supplier getModuleRuleProvider() { } @Override - protected @NonNull AppDeployer appDeployer() { - return AppDeployer.create(InstallerEventModel.SERVICE_DEPLOYMENT, - InstallerEventModel.SERVICE_DEPLOYMENT_TRACKER, - InstallerEventModel.SERVICE_DEPLOYMENT_FINISHER); + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return AppDeployerDefinition.create(InstallerEventModel.SERVICE_DEPLOYMENT, + InstallerEventModel.SERVICE_DEPLOYMENT_TRACKER, + InstallerEventModel.SERVICE_DEPLOYMENT_FINISHER); } @Override diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeApplicationService.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeApplicationService.java new file mode 100644 index 000000000..8ab4aebef --- /dev/null +++ b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeApplicationService.java @@ -0,0 +1,14 @@ +package com.nubeiot.edge.module.installer.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.ApplicationService; + +import lombok.NonNull; + +public final class EdgeApplicationService extends ApplicationService implements EdgeInstallerService { + + public EdgeApplicationService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeBackupByAppService.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeBackupByAppService.java new file mode 100644 index 000000000..779f95b3b --- /dev/null +++ b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeBackupByAppService.java @@ -0,0 +1,14 @@ +package com.nubeiot.edge.module.installer.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.BackupByAppService; + +import lombok.NonNull; + +public final class EdgeBackupByAppService extends BackupByAppService implements EdgeInstallerService { + + protected EdgeBackupByAppService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeInstallerService.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeInstallerService.java index c8304b1fe..df3219af4 100644 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeInstallerService.java +++ b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeInstallerService.java @@ -9,8 +9,8 @@ default String api() { } @Override - default String rootPath() { - return "/services"; + default String appPath() { + return "/service"; } } diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeModuleService.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeModuleService.java deleted file mode 100644 index 824fff52b..000000000 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeModuleService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.nubeiot.edge.module.installer.service; - -import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.service.ModuleService; - -import lombok.NonNull; - -public final class EdgeModuleService extends ModuleService implements EdgeInstallerService { - - public EdgeModuleService(@NonNull InstallerEntityHandler entityHandler) { - super(entityHandler); - } - -} diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByAppService.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByAppService.java new file mode 100644 index 000000000..918b0818e --- /dev/null +++ b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByAppService.java @@ -0,0 +1,14 @@ +package com.nubeiot.edge.module.installer.service; + +import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.service.TransactionByAppService; + +import lombok.NonNull; + +public final class EdgeTransactionByAppService extends TransactionByAppService implements EdgeInstallerService { + + public EdgeTransactionByAppService(@NonNull InstallerEntityHandler entityHandler) { + super(entityHandler); + } + +} diff --git a/settings.gradle b/settings.gradle index 39b8762e2..8bd2ec2c7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,6 +14,7 @@ include ':core:httpclient' include ':core:httpserver' include ':core:protocol' include ':core:auth' +include ':core:archiver' include ':core:kafka' include ':core:scheduler' include ':core:scheduler:model'