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/component/SharedDataDelegate.java b/core/base/src/main/java/com/nubeiot/core/component/SharedDataDelegate.java index ed6d87e2f..30ba29995 100644 --- a/core/base/src/main/java/com/nubeiot/core/component/SharedDataDelegate.java +++ b/core/base/src/main/java/com/nubeiot/core/component/SharedDataDelegate.java @@ -12,6 +12,7 @@ import com.nubeiot.core.event.EventbusClient; import com.nubeiot.core.utils.Strings; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -96,7 +97,7 @@ static Path getDataDir(@NonNull Vertx vertx, String sharedKey) { T registerSharedData(@NonNull Function sharedDataFunc); @Getter - @NoArgsConstructor + @NoArgsConstructor(access = AccessLevel.PROTECTED) abstract class AbstractSharedDataDelegate implements SharedDataDelegate { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -104,7 +105,7 @@ abstract class AbstractSharedDataDelegate implemen private String sharedKey; private Function sharedDataFunc; - public AbstractSharedDataDelegate(@NonNull Vertx vertx) { + protected AbstractSharedDataDelegate(@NonNull Vertx vertx) { this.vertx = vertx; } @@ -129,6 +130,10 @@ protected final T registerSharedKey(String sharedKey) { return (T) this; } + protected Path dataDir() { + return Paths.get((String) getSharedDataValue(SHARED_DATADIR)); + } + } } diff --git a/core/base/src/main/java/com/nubeiot/core/dto/EnumType.java b/core/base/src/main/java/com/nubeiot/core/dto/EnumType.java index 7a4d465e7..8a39e5295 100644 --- a/core/base/src/main/java/com/nubeiot/core/dto/EnumType.java +++ b/core/base/src/main/java/com/nubeiot/core/dto/EnumType.java @@ -14,6 +14,7 @@ import lombok.AccessLevel; import lombok.EqualsAndHashCode; +import lombok.EqualsAndHashCode.Include; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -45,11 +46,12 @@ default Collection alternatives() { return null; } - @EqualsAndHashCode + @EqualsAndHashCode(onlyExplicitlyIncluded = true) @RequiredArgsConstructor(access = AccessLevel.PRIVATE) abstract class AbstractEnumType implements EnumType { @NonNull + @Include private final String type; private final Collection aliases; 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/cache/src/main/java/com/nubeiot/core/cache/CacheInitializer.java b/core/cache/src/main/java/com/nubeiot/core/cache/CacheInitializer.java index 6c3df6eb4..c1671545a 100644 --- a/core/cache/src/main/java/com/nubeiot/core/cache/CacheInitializer.java +++ b/core/cache/src/main/java/com/nubeiot/core/cache/CacheInitializer.java @@ -1,9 +1,22 @@ package com.nubeiot.core.cache; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + +import io.vertx.core.Vertx; + import lombok.NonNull; public interface CacheInitializer { @NonNull R init(@NonNull C context); + @SuppressWarnings("unchecked") + default void addBlockingCache(@NonNull Vertx vertx, @NonNull String cacheKey, + @NonNull Supplier blockingCacheProvider, + @NonNull BiConsumer addSharedDataFunc) { + vertx.executeBlocking(future -> future.complete(blockingCacheProvider.get()), + result -> addSharedDataFunc.accept(cacheKey, (T) result.result())); + } + } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleType.java b/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleType.java deleted file mode 100644 index 3b1160ef0..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleType.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.nubeiot.edge.installer.loader; - -import java.util.Objects; - -import io.vertx.core.json.JsonObject; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.nubeiot.core.utils.Strings; - -import lombok.EqualsAndHashCode; -import lombok.NonNull; - -//TODO Later for other languages (except JAVA) https://github.com/NubeIO/iot-engine/issues/239 -public interface ModuleType { - - static ModuleType getDefault() { - return JAVA; - } - - @JsonCreator - static ModuleType factory(String type) { - if (JAVASCRIPT.name().equalsIgnoreCase(type)) { - return JAVASCRIPT; - } - if (RUBY.name().equalsIgnoreCase(type)) { - return RUBY; - } - if (GROOVY.name().equalsIgnoreCase(type)) { - return GROOVY; - } - if (SCALA.name().equalsIgnoreCase(type)) { - return SCALA; - } - if (KOTLIN.name().equalsIgnoreCase(type)) { - return KOTLIN; - } - return getDefault(); - } - - String name(); - - ModuleType JAVA = new AbstractModuleType() { - - @Override - public String name() { - return "JAVA"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return String.format("maven:%s:%s::%s", serviceId, Strings.isBlank(version) ? DEFAULT_VERSION : version, - serviceName); - } - - private static final String DEFAULT_GROUP_ID = "com.nubeiot.edge.connector"; - private static final String DEFAULT_VERSION = "1.0.0"; - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - final String artifactId = input.getString("artifact_id"); - final String groupId = input.getString("group_id", DEFAULT_GROUP_ID); - final String serviceName = input.getString("service_name", artifactId); - if (Strings.isBlank(artifactId)) { - throw new InvalidModuleType("Missing artifact_id"); - } - if (Objects.nonNull(rule) && !rule.getRule(this).test(groupId + "." + artifactId)) { - throw new InvalidModuleType("Artifact is not valid"); - } - String serviceId = String.format("%s:%s", groupId, artifactId); - return input.mergeIn(new JsonObject(), true) - .put("service_id", serviceId) - .put("service_name", serviceName) - .put("service_type", name()); - } - - }; - ModuleType JAVASCRIPT = new AbstractModuleType() { - @Override - public String name() { - return "JAVASCRIPT"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return null; - } - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - return null; - } - - }; - ModuleType GROOVY = new AbstractModuleType() { - @Override - public String name() { - return "GROOVY"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return null; - } - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - return null; - } - - }; - - - @EqualsAndHashCode - abstract class AbstractModuleType implements ModuleType { - - @EqualsAndHashCode.Include - public abstract String name(); - - @Override - public final String toString() { - return this.name(); - } - - } - - - ModuleType SCALA = new AbstractModuleType() { - @Override - public String name() { - return "SCALA"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return null; - } - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - return null; - } - - }; - ModuleType KOTLIN = new AbstractModuleType() { - @Override - public String name() { - return "KOTLIN"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return null; - } - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - return null; - } - - }; - ModuleType RUBY = new AbstractModuleType() { - @Override - public String name() { - return "RUBY"; - } - - @Override - public String generateFQN(String serviceId, String version, String serviceName) { - return null; - } - - @Override - public JsonObject serialize(JsonObject input, ModuleTypeRule rule) throws InvalidModuleType { - return null; - } - - }; - - String generateFQN(String serviceId, String version, String serviceName); - - JsonObject serialize(@NonNull JsonObject input, @NonNull ModuleTypeRule rule) throws InvalidModuleType; - -} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicate.java b/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicate.java deleted file mode 100644 index 012011fc9..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicate.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.nubeiot.edge.installer.loader; - -import java.util.List; -import java.util.function.Predicate; - -import com.nubeiot.core.utils.Strings; - -import lombok.Getter; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - -interface ModuleTypePredicate extends Predicate { - - List getSearchPattern(); - - default Predicate getRule() { - return this; - } - - @RequiredArgsConstructor - @Getter - abstract class AbstractModuleTypePredicate implements ModuleTypePredicate { - - @NonNull - protected final List searchPattern; - - } - - - class JavaPredicate extends AbstractModuleTypePredicate { - - JavaPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String test) { - if (Strings.isBlank(test)) { - return false; - } - return searchPattern.isEmpty() || this.searchPattern.parallelStream().anyMatch(test::startsWith); - } - - } - - - class JavascriptPredicate extends AbstractModuleTypePredicate { - - JavascriptPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String s) { - return true; - } - - } - - - class GroovyPredicate extends AbstractModuleTypePredicate { - - GroovyPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String test) { - return true; - } - - } - - - class ScalaPredicate extends AbstractModuleTypePredicate { - - ScalaPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String test) { - return true; - } - - } - - - class KotlinPredicate extends AbstractModuleTypePredicate { - - KotlinPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String test) { - return true; - } - - } - - - class RubyPredicate extends AbstractModuleTypePredicate { - - RubyPredicate(@NonNull List searchPattern) { - super(searchPattern); - } - - @Override - public boolean test(String test) { - return true; - } - - } - -} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicateFactory.java b/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicateFactory.java deleted file mode 100644 index 58a569b52..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypePredicateFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.nubeiot.edge.installer.loader; - -import java.util.List; -import java.util.stream.Collectors; - -import com.nubeiot.core.utils.Strings; - -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor(access = AccessLevel.PRIVATE) -final class ModuleTypePredicateFactory { - - static ModuleTypePredicate factory(ModuleType moduleType, List searchPattern) { - List patterns = searchPattern.stream().filter(Strings::isNotBlank).collect(Collectors.toList()); - if (ModuleType.JAVASCRIPT == moduleType) { - return new ModuleTypePredicate.JavascriptPredicate(patterns); - } - - if (ModuleType.GROOVY == moduleType) { - return new ModuleTypePredicate.GroovyPredicate(patterns); - } - - if (ModuleType.SCALA == moduleType) { - return new ModuleTypePredicate.ScalaPredicate(patterns); - } - - if (ModuleType.KOTLIN == moduleType) { - return new ModuleTypePredicate.KotlinPredicate(patterns); - } - - if (ModuleType.RUBY == moduleType) { - return new ModuleTypePredicate.RubyPredicate(patterns); - } - - return new ModuleTypePredicate.JavaPredicate(patterns); - } - -} 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 deleted file mode 100644 index 5ae555971..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/ModuleTypeRule.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.nubeiot.edge.installer.loader; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Predicate; - -import io.vertx.core.json.JsonObject; -import io.vertx.core.shareddata.Shareable; - -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 lombok.AccessLevel; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor(access = AccessLevel.PRIVATE) -public final class ModuleTypeRule implements Shareable { - - private final Map rules; - - 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 ITblModule 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); - } - - 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; - } - - private JsonObject computeAppSystemConfig(@NonNull Path parentDataDir, String serviceId) { - return NubeConfig.blank(FileUtils.recomputeDataDir(parentDataDir, FileUtils.normalize(serviceId))).toJson(); - } - - public ModuleTypeRule registerRule(ModuleType moduleType, List searchPattern) { - rules.put(moduleType, ModuleTypePredicateFactory.factory(moduleType, searchPattern)); - return this; - } - - public Predicate getRule(ModuleType moduleType) { - final ModuleTypePredicate ruleMetadata = this.rules.get(moduleType); - return Objects.isNull(ruleMetadata) ? any -> false : ruleMetadata.getRule(); - } - - public List getSearchPattern(ModuleType moduleType) { - final ModuleTypePredicate ruleMetadata = this.rules.get(moduleType); - return Objects.isNull(ruleMetadata) ? new ArrayList<>() : ruleMetadata.getSearchPattern(); - } - - @Override - public Shareable copy() { - return new ModuleTypeRule(Collections.unmodifiableMap(this.rules)); - } - -} 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/AppDeployer.java deleted file mode 100644 index 75b3eeac1..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeployer.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.nubeiot.edge.installer.service; - -import io.vertx.core.shareddata.Shareable; - -import com.nubeiot.core.event.EventModel; -import com.nubeiot.edge.installer.InstallerEntityHandler; - -import lombok.NonNull; - -/** - * Application service deployer definition - */ -public interface AppDeployer extends Shareable { - - static AppDeployer create(@NonNull EventModel loaderEvent, @NonNull EventModel trackerEvent, - @NonNull EventModel finisherEvent) { - return new DefaultAppDeployer(loaderEvent, trackerEvent, finisherEvent); - } - - /** - * Defines deployment loader event - * - * @return loader event - */ - @NonNull EventModel getLoaderEvent(); - - /** - * Defines tracker event after finish deploying - * - * @return tracker event - */ - @NonNull EventModel getTrackerEvent(); - - /** - * Defines finisher event after finish deploy and update database - * - * @return finisher event - */ - @NonNull EventModel getFinisherEvent(); - - /** - * Register event service - * - * @param entityHandler Entity handler - */ - void register(@NonNull InstallerEntityHandler entityHandler); - -} 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/DefaultAppDeployer.java deleted file mode 100644 index 79fecab12..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployer.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.nubeiot.edge.installer.service; - -import com.nubeiot.core.event.EventModel; -import com.nubeiot.edge.installer.InstallerEntityHandler; - -import lombok.Getter; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -final class DefaultAppDeployer implements AppDeployer { - - @NonNull - private final EventModel loaderEvent; - @NonNull - private final EventModel trackerEvent; - @NonNull - private final EventModel finisherEvent; - - @Override - public void register(@NonNull InstallerEntityHandler entityHandler) { - entityHandler.eventClient() - .register(getLoaderEvent(), new AppDeploymentService(entityHandler)) - .register(getTrackerEvent(), new AppDeploymentTracker(entityHandler)) - .register(getFinisherEvent(), new AppDeploymentFinisher(entityHandler)); - } - -} 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 deleted file mode 100644 index a55cf46de..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.nubeiot.edge.installer.service; - -import com.nubeiot.core.event.EventListener; - -public interface DeploymentService extends EventListener { - - 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 deleted file mode 100644 index 4d7f12348..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerApiIndex.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.nubeiot.edge.installer.service; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.jooq.OrderField; - -import com.nubeiot.core.sql.EntityMetadata; -import com.nubeiot.core.sql.EntityMetadata.StringKeyEntity; -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 lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@SuppressWarnings("unchecked") -public interface InstallerApiIndex extends MetadataIndex { - - List INDEX = Collections.unmodifiableList(MetadataIndex.find(InstallerApiIndex.class)); - - @Override - default List index() { - return INDEX; - } - - @NoArgsConstructor(access = AccessLevel.PRIVATE) - final class AppServiceMetadata implements StringKeyEntity { - - public static final AppServiceMetadata INSTANCE = new AppServiceMetadata(); - - @Override - public @NonNull com.nubeiot.edge.installer.model.tables.TblModule table() { - return Tables.TBL_MODULE; - } - - @Override - public @NonNull Class modelClass() { - return TblModule.class; - } - - @Override - public @NonNull Class daoClass() { - return TblModuleDao.class; - } - - @Override - public @NonNull String requestKeyName() { return "transaction_id"; } - - @Override - public @NonNull String singularKeyName() { return "transaction"; } - - @Override - public @NonNull List> orderFields() { - return Arrays.asList(table().STATE, table().SERVICE_TYPE, table().SERVICE_ID); - } - - } - - - @NoArgsConstructor(access = AccessLevel.PRIVATE) - final class TransactionMetadata - implements StringKeyEntity { - - public static final TransactionMetadata INSTANCE = new TransactionMetadata(); - - @Override - public @NonNull com.nubeiot.edge.installer.model.tables.TblTransaction table() { - return Tables.TBL_TRANSACTION; - } - - @Override - public @NonNull Class modelClass() { - return TblTransaction.class; - } - - @Override - public @NonNull Class daoClass() { - return TblTransactionDao.class; - } - - @Override - public @NonNull String requestKeyName() { return "transaction_id"; } - - @Override - public @NonNull String singularKeyName() { return "transaction"; } - - @Override - public @NonNull List> orderFields() { - return Arrays.asList(table().MODULE_ID, table().MODIFIED_AT.desc()); - } - - } - - - @NoArgsConstructor(access = AccessLevel.PRIVATE) - final class HistoryMetadata - 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; - } - - @Override - public @NonNull Class modelClass() { - return TblRemoveHistory.class; - } - - @Override - public @NonNull Class daoClass() { - return TblRemoveHistoryDao.class; - } - - @Override - public @NonNull String requestKeyName() { return "transaction_id"; } - - @Override - public @NonNull String singularKeyName() { return "transaction"; } - - @Override - public @NonNull List> orderFields() { - return Arrays.asList(table().MODULE_ID, table().MODIFIED_AT.desc()); - } - - } - -} 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 deleted file mode 100644 index f8325d886..000000000 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.nubeiot.edge.installer.service; - -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; -import com.nubeiot.core.http.base.event.EventMethodDefinition; -import com.nubeiot.core.utils.Reflections.ReflectionClass; -import com.nubeiot.edge.installer.InstallerEntityHandler; - -public interface InstallerService extends EventHttpService { - - static Set createServices(InstallerEntityHandler entityHandler, - Class serviceClazz) { - final Map inputs = Collections.singletonMap(InstallerEntityHandler.class, entityHandler); - return ReflectionClass.stream(serviceClazz.getPackage().getName(), serviceClazz, ReflectionClass.publicClass()) - .map(clazz -> ReflectionClass.createObject(clazz, inputs)) - .filter(Objects::nonNull) - .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)); - } - - String rootPath(); - - String servicePath(); - - String paramPath(); - -} diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/loader/ModuleTypeRuleTest.java b/core/installer/src/test/java/com/nubeiot/edge/installer/loader/ModuleTypeRuleTest.java deleted file mode 100644 index b4fc0a078..000000000 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/loader/ModuleTypeRuleTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.nubeiot.edge.installer.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; - -import org.junit.Test; - -// TODO mock and test with different language https://github.com/NubeIO/iot-engine/issues/239 -public class ModuleTypeRuleTest { - - @Test - public void testRule() { - ModuleTypeRule moduleTypeRule = new ModuleTypeRule().registerRule(ModuleType.JAVA, - Collections.singletonList("")); - assertFalse(moduleTypeRule.getRule(ModuleType.JAVA).test(null)); - assertFalse(moduleTypeRule.getRule(ModuleType.JAVA).test("")); - } - - @Test - public void testOneGroup() { - ModuleTypeRule moduleTypeRule = new ModuleTypeRule().registerRule(ModuleType.JAVA, Collections.singletonList( - "com.nubeio.edge.connector")); - assertTrue(moduleTypeRule.getRule(ModuleType.JAVA).test("com.nubeio.edge.connector")); - final List searchPattern = moduleTypeRule.getSearchPattern(ModuleType.JAVA); - assertEquals(1, searchPattern.size()); - assertEquals("com.nubeio.edge.connector", searchPattern.get(0)); - } - - @Test - public void testManyGroups() { - List groups = Arrays.asList("group1", "group2", "group3"); - ModuleTypeRule moduleTypeRule = new ModuleTypeRule().registerRule(ModuleType.JAVA, groups); - Predicate javaRule = moduleTypeRule.getRule(ModuleType.JAVA); - groups.forEach(item -> assertTrue(javaRule.test(item))); - assertFalse(javaRule.test("group4")); - } - - @Test - public void testDifferentModuleType() { - final List javaSearchPattern = Arrays.asList("group1", "group2"); - final List jsSearchPattern = Arrays.asList("group3", "group4"); - ModuleTypeRule rule = new ModuleTypeRule().registerRule(ModuleType.JAVA, javaSearchPattern) - .registerRule(ModuleType.JAVASCRIPT, jsSearchPattern); - assertTrue(rule.getRule(ModuleType.JAVA).test("group1.abc")); - assertEquals(javaSearchPattern, rule.getSearchPattern(ModuleType.JAVA)); - assertTrue(rule.getRule(ModuleType.JAVASCRIPT).test("abc")); - assertEquals(jsSearchPattern, rule.getSearchPattern(ModuleType.JAVASCRIPT)); - assertFalse(rule.getRule(ModuleType.GROOVY).test("xxx")); - assertEquals(0, rule.getSearchPattern(ModuleType.GROOVY).size()); - } - -} 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/build.gradle b/edge/bios/build.gradle index d89147376..e460870d2 100644 --- a/edge/bios/build.gradle +++ b/edge/bios/build.gradle @@ -4,10 +4,9 @@ ext { } dependencies { - compile project(':core:installer') + compile project(':edge:installer:service') compile project(':eventbus:edge:gateway') - compile project(':eventbus:edge:installer') testCompile project(":core:base").sourceSets.test.output - testCompile project(":core:installer").sourceSets.test.output + testCompile project(":edge:installer:service").sourceSets.test.output } 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..0a19900e4 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,8 +29,8 @@ protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule t return appConfig; } - protected TblModule decorateModule(TblModule m) { - return super.decorateModule(m).setPublishedBy("NubeIO"); + protected Application decorateApp(Application m) { + return super.decorateApp(m).setPublishedBy("NubeIO"); } } diff --git a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosRuleProvider.java b/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosRuleProvider.java deleted file mode 100644 index 261b9f690..000000000 --- a/edge/bios/src/main/java/com/nubeiot/edge/bios/EdgeBiosRuleProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.nubeiot.edge.bios; - -import java.util.Collections; -import java.util.function.Supplier; - -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.loader.ModuleTypeRule; - -final class EdgeBiosRuleProvider implements Supplier { - - @Override - public ModuleTypeRule get() { - return new ModuleTypeRule().registerRule(ModuleType.JAVA, Collections.singletonList("com.nubeiot.edge.module")); - } - -} 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..6d1a9ca10 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 @@ -6,10 +6,9 @@ import com.nubeiot.edge.bios.service.BiosInstallerService; 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.rule.RuleRepository; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.InstallerService; -import com.nubeiot.eventbus.edge.installer.InstallerEventModel; import lombok.NonNull; @@ -21,14 +20,13 @@ protected Class entityHandlerClass() { } @Override - protected Supplier getModuleRuleProvider() { - return new EdgeBiosRuleProvider(); + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return AppDeployerDefinition.create("bios"); } @Override - protected @NonNull AppDeployer appDeployer() { - return AppDeployer.create(InstallerEventModel.BIOS_DEPLOYMENT, InstallerEventModel.BIOS_DEPLOYMENT_TRACKER, - InstallerEventModel.BIOS_DEPLOYMENT_FINISHER); + protected @NonNull RuleRepository ruleRepository() { + return RuleRepository.createJVMRule("com.nubeiot.edge.module"); } @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/EdgeBiosRuleProviderTest.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/EdgeBiosRuleProviderTest.java deleted file mode 100644 index 91262dfd8..000000000 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/EdgeBiosRuleProviderTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.nubeiot.edge.bios; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.loader.ModuleTypeRule; - -public class EdgeBiosRuleProviderTest { - - private ModuleTypeRule rule; - - @Before - public void setup() { - this.rule = new EdgeBiosRuleProvider().get(); - } - - @Test - public void test_ModuleTypeJAVA_success() { - assertTrue(rule.getRule(ModuleType.JAVA).test("com.nubeiot.edge.module.xyz")); - final List searchPattern = rule.getSearchPattern(ModuleType.JAVA); - assertEquals(1, searchPattern.size()); - assertTrue(searchPattern.contains("com.nubeiot.edge.module")); - } - - @Test - public void test_ModuleTypeJAVA_failed() { - assertFalse(rule.getRule(ModuleType.JAVA).test("com.nubeiot.edge.ccc.xyz")); - } - - @Test - public void test_ModuleTypeJAVAScript() { - assertFalse(rule.getRule(ModuleType.JAVASCRIPT).test("olala")); - } - -} 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..55e9e56c5 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; @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(VertxModuleType.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..3564fc919 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 @@ -12,8 +12,8 @@ import com.nubeiot.core.utils.DateTimes; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; @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(VertxModuleType.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..bf644270d 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 @@ -14,8 +14,8 @@ import com.nubeiot.core.utils.DateTimes; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; @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(VertxModuleType.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..1c502d303 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 @@ -13,8 +13,8 @@ import com.nubeiot.core.utils.DateTimes; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; @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(VertxModuleType.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..7c9449964 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,9 +13,9 @@ 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; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; public interface DeploymentAsserter extends Consumer { @@ -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/loader/MockFailedModuleLoader.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockFailedModuleLoader.java index 9594ea69a..f064fb4f1 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockFailedModuleLoader.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockFailedModuleLoader.java @@ -12,7 +12,7 @@ import com.nubeiot.core.event.EventContractor; import com.nubeiot.core.event.EventListener; import com.nubeiot.core.exceptions.EngineException; -import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; import lombok.NonNull; import lombok.RequiredArgsConstructor; diff --git a/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockModuleLoader.java b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockModuleLoader.java index fb07972e7..02c1f1551 100644 --- a/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockModuleLoader.java +++ b/edge/bios/src/test/java/com/nubeiot/edge/bios/loader/MockModuleLoader.java @@ -12,7 +12,7 @@ import com.nubeiot.core.event.EventAction; import com.nubeiot.core.event.EventContractor; import com.nubeiot.core.event.EventListener; -import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; import lombok.NonNull; import lombok.RequiredArgsConstructor; 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..d3615788b 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 @@ -8,8 +8,8 @@ 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..c0054e1b3 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 @@ -14,9 +14,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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(VertxModuleType.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(VertxModuleType.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(VertxModuleType.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(VertxModuleType.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..ac488028b 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 @@ -5,22 +5,19 @@ import io.reactivex.Single; import io.vertx.core.Vertx; -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; 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 @@ -31,11 +28,6 @@ abstract class MockInitDataEntityHandler extends InstallerEntityHandler { // .map(r -> EventMessage.success(EventAction.INIT, new JsonObject().put("records", r))); // } - @Override - protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule tblModule, AppConfig appConfig) { - return appConfig; - } - protected abstract Single initModules(); } 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..5a1d9864f 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 @@ -12,9 +12,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..876d2110b 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 @@ -12,9 +12,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..3e1f52693 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 @@ -12,9 +12,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..3926fd4fa 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 @@ -14,9 +14,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..1941ecb81 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 @@ -12,9 +12,9 @@ import com.nubeiot.core.enums.Status; 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; +import com.nubeiot.edge.installer.model.type.VertxModuleType; 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(VertxModuleType.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..6a358a352 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 @@ -20,12 +20,13 @@ import com.nubeiot.core.enums.Status; import com.nubeiot.core.event.DeliveryEvent; import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventModel; import com.nubeiot.core.utils.DateTimes; 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.eventbus.edge.installer.InstallerEventModel; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.type.VertxModuleType; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; @Ignore public class HandlerTimeoutTest extends BaseInstallerVerticleTest { @@ -33,14 +34,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(VertxModuleType.JAVA) + .setServiceName(SERVICE_NAME) + .setState(State.ENABLED) + .setVersion(VERSION) + .setAppConfig(APP_CONFIG) + .setSystemConfig(APP_SYSTEM_CONFIG) + .setModifiedAt(DateTimes.now())); } @Override @@ -72,12 +73,12 @@ public void test_patch_no_time_out(TestContext context) { final JsonObject expected = new JsonObject().put("status", Status.SUCCESS) .put("action", EventAction.PATCH) .put("data", expectedBody); - this.installerVerticle.getEventbusClient().fire( - DeliveryEvent.from(MockTimeoutVerticle.MOCK_TIME_OUT_INSTALLER, EventAction.PATCH, - RequestData.builder().body(body).build().toJson()), - EventbusHelper.replyAsserter(context, async, expected, - JsonHelper.ignore("data.transaction_id"), - JsonHelper.ignore("data.system_config"))); + this.installerVerticle.getEventbusClient() + .fire(DeliveryEvent.from(MockTimeoutVerticle.MOCK_TIME_OUT_INSTALLER, EventAction.PATCH, + RequestData.builder().body(body).build().toJson()), + EventbusHelper.replyAsserter(context, async, expected, + JsonHelper.ignore("data.transaction_id"), + JsonHelper.ignore("data.system_config"))); this.testingDBUpdated(context, State.ENABLED, Status.SUCCESS, APP_CONFIG); } @@ -93,8 +94,10 @@ public void test_patch_directly_no_time_out(TestContext context) { final JsonObject expected = new JsonObject().put("status", Status.SUCCESS) .put("action", EventAction.PATCH) .put("data", new JsonObject("{\"abc\":\"123\"}")); + final EventModel event = AppDeployerDefinition.createExecuterEvent( + AppDeployerDefinition.createExecuterAddr("bios")); this.installerVerticle.getEventbusClient() - .fire(DeliveryEvent.from(InstallerEventModel.BIOS_DEPLOYMENT, EventAction.PATCH, + .fire(DeliveryEvent.from(event, EventAction.PATCH, RequestData.builder().body(body).build().toJson()), EventbusHelper.replyAsserter(context, async, expected)); } @@ -106,7 +109,9 @@ public void test_send_request_directly_should_timeout(TestContext context) { .put("version", VERSION); JsonObject body = new JsonObject().put("metadata", metadata).put("appConfig", APP_CONFIG); Async async = context.async(); - final DeliveryEvent deliveryEvent = DeliveryEvent.from(InstallerEventModel.BIOS_DEPLOYMENT, EventAction.CREATE, + final EventModel event = AppDeployerDefinition.createExecuterEvent( + AppDeployerDefinition.createExecuterAddr("bios")); + final DeliveryEvent deliveryEvent = DeliveryEvent.from(event, EventAction.CREATE, RequestData.builder().body(body).build().toJson()); //create loading takes 9 seconds when timeout is 3 seconds this.installerVerticle.getEventbusClient().fire(deliveryEvent, context.asyncAssertFailure(throwable -> { 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/connector/bacnet/src/main/java/com/nubeiot/edge/connector/bacnet/cache/BACnetCacheInitializer.java b/edge/connector/bacnet/src/main/java/com/nubeiot/edge/connector/bacnet/cache/BACnetCacheInitializer.java index 7b73cc892..8654f8d79 100644 --- a/edge/connector/bacnet/src/main/java/com/nubeiot/edge/connector/bacnet/cache/BACnetCacheInitializer.java +++ b/edge/connector/bacnet/src/main/java/com/nubeiot/edge/connector/bacnet/cache/BACnetCacheInitializer.java @@ -1,7 +1,5 @@ package com.nubeiot.edge.connector.bacnet.cache; -import java.util.function.Supplier; - import com.nubeiot.core.cache.CacheInitializer; import com.nubeiot.core.utils.Strings; import com.nubeiot.edge.connector.bacnet.BACnetConfig; @@ -25,17 +23,11 @@ public final class BACnetCacheInitializer implements CacheInitializer BACnetDeviceCache.init(context.getVertx(), context.getSharedKey())); + addBlockingCache(context.getVertx(), EDGE_NETWORK_CACHE, BACnetNetworkCache::init, context::addSharedData); + addBlockingCache(context.getVertx(), BACNET_DEVICE_CACHE, + () -> BACnetDeviceCache.init(context.getVertx(), context.getSharedKey()), + context::addSharedData); return this; } - private void addBlockingCache(@NonNull BACnetVerticle context, @NonNull String cacheKey, - @NonNull Supplier blockingCacheProvider) { - context.getVertx() - .executeBlocking(future -> future.complete(blockingCacheProvider.get()), - result -> context.addSharedData(cacheKey, result.result())); - } - } diff --git a/core/installer/README.md b/edge/installer/README.md similarity index 100% rename from core/installer/README.md rename to edge/installer/README.md diff --git a/core/installer/build.gradle b/edge/installer/model/build.gradle similarity index 71% rename from core/installer/build.gradle rename to edge/installer/model/build.gradle index 1b49c2a09..00dbe033a 100644 --- a/core/installer/build.gradle +++ b/edge/installer/model/build.gradle @@ -6,15 +6,9 @@ import com.nubeiot.buildscript.jooq.JooqGenerateTask import com.nubeiot.buildscript.jooq.JooqGenerateTask.JsonDataType dependencies { - compile project(':core:base') - compile project(':core:auth') compile project(':core:sql') compile project(':core:micro') - compile project(':eventbus:edge') compile project.deps.database.h2 - compile "io.vertx:vertx-maven-service-factory:$project.versions.vertx" - - testCompile project(":core:base").sourceSets.test.output } task jooqGen(type: JooqGenerateTask) { @@ -22,15 +16,15 @@ task jooqGen(type: JooqGenerateTask) { doFirst { enumTypes = project(':core:sql').ext.enumTypes dbTypes = project(':core:sql').ext.dbTypes + [ - new ForcedType(userType: "com.nubeiot.edge.installer.loader.ModuleType", types: DB.TYPES.varchar, + new ForcedType(userType: "com.nubeiot.edge.installer.model.type.ModuleType", types: DB.TYPES.varchar, expression: Strings.toRegexIgnoreCase("service_type"), converter: "com.nubeiot.edge.installer.model.converter.ModuleTypeConverter") ] javaTypes = project(':core:sql').ext.javaTypes + [ - new JsonDataType(className: "com.nubeiot.edge.installer.loader.ModuleType", - converter: "%s.name()", - parser: "com.nubeiot.edge.installer.loader.ModuleType.factory((String)%s)", - defVal: "com.nubeiot.edge.installer.loader.ModuleType.getDefault()") + new JsonDataType(className: "com.nubeiot.edge.installer.model.type.ModuleType", + converter: "%s.type()", + parser: "com.nubeiot.edge.installer.model.type.ModuleType.factory((String)%s)", + defVal: "com.nubeiot.edge.installer.model.type.ModuleType.getDefault()") ] } diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InstallerApiIndex.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InstallerApiIndex.java new file mode 100644 index 000000000..c9ca1f2fd --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InstallerApiIndex.java @@ -0,0 +1,178 @@ +package com.nubeiot.edge.installer.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.jooq.OrderField; + +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.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; +import lombok.NonNull; + +@SuppressWarnings("unchecked") +public interface InstallerApiIndex extends MetadataIndex { + + List INDEX = Collections.unmodifiableList(MetadataIndex.find(InstallerApiIndex.class)); + + @Override + default List index() { + return INDEX; + } + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + final class ApplicationMetadata implements StringKeyEntity { + + public static final ApplicationMetadata INSTANCE = new ApplicationMetadata(); + + @Override + public @NonNull com.nubeiot.edge.installer.model.tables.Application table() { + return Tables.APPLICATION; + } + + @Override + public @NonNull Class modelClass() { + return Application.class; + } + + @Override + public @NonNull Class daoClass() { + return ApplicationDao.class; + } + + @Override + public @NonNull String requestKeyName() { return "app_id"; } + + @Override + public @NonNull String singularKeyName() { return "app"; } + + @Override + public @NonNull List> orderFields() { + return Arrays.asList(table().STATE, table().SERVICE_TYPE, table().APP_ID); + } + + } + + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + final class TransactionMetadata + implements StringKeyEntity { + + public static final TransactionMetadata INSTANCE = new TransactionMetadata(); + + @Override + public @NonNull com.nubeiot.edge.installer.model.tables.DeployTransaction table() { + return Tables.DEPLOY_TRANSACTION; + } + + @Override + public @NonNull Class modelClass() { + return DeployTransaction.class; + } + + @Override + public @NonNull Class daoClass() { + return DeployTransactionDao.class; + } + + @Override + public @NonNull String requestKeyName() { return "transaction_id"; } + + @Override + public @NonNull String singularKeyName() { return "transaction"; } + + @Override + public @NonNull List> orderFields() { + return Arrays.asList(table().APP_ID, table().MODIFIED_AT.desc()); + } + + } + + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + final class HistoryMetadata + implements StringKeyEntity { + + public static final HistoryMetadata INSTANCE = new HistoryMetadata(); + + @Override + public @NonNull com.nubeiot.edge.installer.model.tables.ApplicationHistory table() { + return Tables.APPLICATION_HISTORY; + } + + @Override + public @NonNull Class modelClass() { + return ApplicationHistory.class; + } + + @Override + public @NonNull Class daoClass() { + return ApplicationHistoryDao.class; + } + + @Override + public @NonNull String requestKeyName() { return "transaction_id"; } + + @Override + public @NonNull String singularKeyName() { return "transaction"; } + + @Override + public @NonNull List> orderFields() { + 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/loader/InvalidModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InvalidModuleType.java similarity index 90% rename from core/installer/src/main/java/com/nubeiot/edge/installer/loader/InvalidModuleType.java rename to edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InvalidModuleType.java index fb0ef6ed1..3e08ad853 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/loader/InvalidModuleType.java +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/InvalidModuleType.java @@ -1,4 +1,4 @@ -package com.nubeiot.edge.installer.loader; +package com.nubeiot.edge.installer.model; import com.nubeiot.core.exceptions.NubeException; diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java similarity index 81% rename from core/installer/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java rename to edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java index ef05e13d0..6afa0dfa6 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/converter/ModuleTypeConverter.java @@ -4,7 +4,7 @@ import org.jooq.Converter; -import com.nubeiot.edge.installer.loader.ModuleType; +import com.nubeiot.edge.installer.model.type.ModuleType; public final class ModuleTypeConverter implements Converter { @@ -15,7 +15,7 @@ public ModuleType from(String databaseObject) { @Override public String to(ModuleType userObject) { - return Objects.isNull(userObject) ? null : userObject.name(); + return Objects.isNull(userObject) ? null : userObject.type(); } @Override diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableArchiverModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableArchiverModuleType.java new file mode 100644 index 000000000..7f2ff918b --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableArchiverModuleType.java @@ -0,0 +1,24 @@ +package com.nubeiot.edge.installer.model.type; + +import io.vertx.core.json.JsonObject; + +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; + +import lombok.NonNull; + +public interface ExecutableArchiverModuleType extends ExecutableBinaryModuleType { + + @NonNull ExecutableBinaryModuleType binaryType(); + + @Override + default String generateFQN(String appId, String version, String serviceName) { + return protocol() + binaryType().generateFQN(appId, version, serviceName); + } + + @Override + default IApplication serialize(@NonNull JsonObject request) throws InvalidModuleType { + return binaryType().serialize(request); + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableBinaryModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableBinaryModuleType.java new file mode 100644 index 000000000..5ee39ddbe --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ExecutableBinaryModuleType.java @@ -0,0 +1,36 @@ +package com.nubeiot.edge.installer.model.type; + +import com.fasterxml.jackson.annotation.JsonCreator; + +import lombok.NonNull; + +/** + * Represents {@code Executable Binary} module type. + * + * @since 1.0.0 + */ +public interface ExecutableBinaryModuleType extends ModuleType { + + ExecutableBinaryModuleType NODEJS_BINARY = new ExecutableBinaryModuleType() { + @Override + public String type() { + return "NODEJS_BINARY"; + } + + @Override + public String generateFQN(String appId, String version, String serviceName) { + return null; + } + }; + + @JsonCreator + static ExecutableBinaryModuleType factory(@NonNull String type) { + return ModuleTypeFactory.factory(type, ExecutableBinaryModuleType.class); + } + + @Override + default String protocol() { + return "binary"; + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/HttpExecutableArchiverModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/HttpExecutableArchiverModuleType.java new file mode 100644 index 000000000..523616e10 --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/HttpExecutableArchiverModuleType.java @@ -0,0 +1,31 @@ +package com.nubeiot.edge.installer.model.type; + +import com.fasterxml.jackson.annotation.JsonCreator; + +import lombok.NonNull; + +public interface HttpExecutableArchiverModuleType extends LocalExecutableArchiverModuleType { + + HttpExecutableArchiverModuleType HTTP_NODEJS_ARCHIVER = new HttpExecutableArchiverModuleType() { + @Override + public ExecutableBinaryModuleType binaryType() { + return LocalExecutableArchiverModuleType.NODEJS_ARCHIVER.binaryType(); + } + + @Override + public String type() { + return "HTTP_NODEJS_ARCHIVER"; + } + }; + + @JsonCreator + static HttpExecutableArchiverModuleType factory(@NonNull String type) { + return ModuleTypeFactory.factory(type, HttpExecutableArchiverModuleType.class); + } + + @Override + default @NonNull String protocol() { + return "http"; + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/LocalExecutableArchiverModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/LocalExecutableArchiverModuleType.java new file mode 100644 index 000000000..184a480fb --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/LocalExecutableArchiverModuleType.java @@ -0,0 +1,31 @@ +package com.nubeiot.edge.installer.model.type; + +import com.fasterxml.jackson.annotation.JsonCreator; + +import lombok.NonNull; + +public interface LocalExecutableArchiverModuleType extends ExecutableArchiverModuleType { + + LocalExecutableArchiverModuleType NODEJS_ARCHIVER = new LocalExecutableArchiverModuleType() { + @Override + public ExecutableBinaryModuleType binaryType() { + return NODEJS_BINARY; + } + + @Override + public String type() { + return "LOCAL_NODEJS_ARCHIVER"; + } + }; + + @JsonCreator + static LocalExecutableArchiverModuleType factory(@NonNull String type) { + return ModuleTypeFactory.factory(type, LocalExecutableArchiverModuleType.class); + } + + @Override + default @NonNull String protocol() { + return "file"; + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleType.java new file mode 100644 index 000000000..b108e4925 --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleType.java @@ -0,0 +1,82 @@ +package com.nubeiot.edge.installer.model.type; + +import io.vertx.core.json.JsonObject; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.nubeiot.core.dto.EnumType; +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; + +import lombok.NonNull; + +/** + * The interface Module type. + * + * @since 1.0.0 + */ +public interface ModuleType extends EnumType { + + /** + * Defines default module type + * + * @return the default + * @since 1.0.0 + */ + static ModuleType getDefault() { + return VertxModuleType.JAVA; + } + + /** + * Factory module type. + * + * @param type the type + * @return the module type + * @since 1.0.0 + */ + @JsonCreator + static ModuleType factory(String type) { + return ModuleTypeFactory.factory(type); + } + + /** + * Defines module type + * + * @return the module type + * @since 1.0.0 + */ + String type(); + + /** + * Defines service factory protocol to get artifact from remote/local repository + * + * @return the service factory protocol + * @since 1.0.0 + */ + String protocol(); + + /** + * Generate full qualified name. + * + * @param appId the app id + * @param version the version + * @param serviceName the service name + * @return the string + * @since 1.0.0 + */ + String generateFQN(@NonNull String appId, String version, String serviceName); + + /** + * Serialize request json to application model. + * + * @param request the input + * @return the application + * @throws InvalidModuleType the invalid module type + * @see IApplication + * @since 1.0.0 + */ + default IApplication serialize(@NonNull JsonObject request) throws InvalidModuleType { + return new Application(request).setServiceType(this); + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleTypeFactory.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleTypeFactory.java new file mode 100644 index 000000000..b90d604d3 --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/ModuleTypeFactory.java @@ -0,0 +1,33 @@ +package com.nubeiot.edge.installer.model.type; + +import java.util.Objects; +import java.util.stream.Stream; + +import com.nubeiot.core.utils.Reflections.ReflectionField; +import com.nubeiot.core.utils.Reflections.ReflectionMethod; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +final class ModuleTypeFactory { + + static T factory(@NonNull String type, @NonNull Class clazz) { + return ReflectionField.streamConstants(clazz) + .filter(vmt -> vmt.type().equalsIgnoreCase(type)) + .findFirst() + .orElse(null); + } + + static ModuleType factory(String type) { + return Stream.of(VertxModuleType.class, ExecutableBinaryModuleType.class, + LocalExecutableArchiverModuleType.class, HttpExecutableArchiverModuleType.class) + .map(clazz -> ReflectionMethod.executeStatic(clazz, "factory", type)) + .filter(Objects::nonNull) + .map(ModuleType.class::cast) + .findFirst() + .orElseGet(ModuleType::getDefault); + } + +} diff --git a/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/VertxModuleType.java b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/VertxModuleType.java new file mode 100644 index 000000000..b899de350 --- /dev/null +++ b/edge/installer/model/src/main/java/com/nubeiot/edge/installer/model/type/VertxModuleType.java @@ -0,0 +1,154 @@ +package com.nubeiot.edge.installer.model.type; + +import java.util.Arrays; +import java.util.function.Predicate; + +import io.vertx.core.json.JsonObject; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.nubeiot.core.utils.Strings; +import com.nubeiot.edge.installer.model.InstallerApiIndex.ApplicationMetadata; +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.tables.pojos.Application; + +import lombok.NonNull; + +/** + * Represents {@code Vertx} polyglot module type. + * + * @since 1.0.0 + */ +public interface VertxModuleType extends ModuleType { + + /** + * The constant DEFAULT_VERSION. + */ + String DEFAULT_VERSION = "1.0.0"; + + /** + * The constant JAVA. + */ + VertxModuleType JAVA = (JVMModuleType) () -> "JAVA"; + + /** + * The constant GROOVY. + */ + VertxModuleType GROOVY = (JVMModuleType) () -> "GROOVY"; + + /** + * The constant KOTLIN. + */ + VertxModuleType KOTLIN = (JVMModuleType) () -> "KOTLIN"; + + /** + * The constant SCALA. + */ + VertxModuleType SCALA = (JVMModuleType) () -> "SCALA"; + + /** + * The constant JAVASCRIPT. + */ + VertxModuleType JAVASCRIPT = new VertxModuleType() { + @Override + public String type() { + return "JAVASCRIPT"; + } + + @Override + public String protocol() { + return null; + } + + @Override + public String generateFQN(String appId, String version, String serviceName) { + return null; + } + }; + + /** + * The constant RUBY. + */ + VertxModuleType RUBY = new VertxModuleType() { + @Override + public String type() { + return "RUBY"; + } + + @Override + public String protocol() { + return null; + } + + @Override + public String generateFQN(String appId, String version, String serviceName) { + return null; + } + }; + + /** + * Factory vertx module type. + * + * @param type the type + * @return the vertx module type + * @since 1.0.0 + */ + @JsonCreator + static VertxModuleType factory(@NonNull String type) { + return ModuleTypeFactory.factory(type, VertxModuleType.class); + } + + /** + * The interface {@code JVM} module type. + * + * @since 1.0.0 + */ + interface JVMModuleType extends VertxModuleType { + + String DEFAULT_GROUP_ID = "com.nubeiot.edge.connector"; + + static Predicate rulePredicate(@NonNull String... artifactGroups) { + return appId -> { + if (Strings.isBlank(appId)) { + return false; + } + final String group = appId.replaceAll(":", "."); + return Arrays.stream(artifactGroups).parallel().anyMatch(group::startsWith); + }; + } + + @Override + default String protocol() { + return "maven"; + } + + @Override + default String generateFQN(String appId, String version, String serviceName) { + return String.format("%s:%s:%s::%s", protocol(), appId, + Strings.isBlank(version) ? DEFAULT_VERSION : version, serviceName); + } + + @Override + default IApplication serialize(@NonNull JsonObject request) throws InvalidModuleType { + final com.nubeiot.edge.installer.model.tables.@NonNull Application table + = ApplicationMetadata.INSTANCE.table(); + final String idField = table.getJsonField(table.APP_ID); + final String serviceId = request.getString(idField); + if (Strings.isNotBlank(serviceId)) { + return VertxModuleType.super.serialize(request); + } + final String artifactId = request.getString("artifact_id"); + final String groupId = request.getString("group_id", DEFAULT_GROUP_ID); + final String serviceName = request.getString("service_name", artifactId); + if (Strings.isBlank(artifactId)) { + throw new InvalidModuleType("Missing artifact_id"); + } + return new Application(request.mergeIn(new JsonObject(), true) + .put(idField, String.format("%s:%s", groupId, artifactId)) + .put(table.getJsonField(table.SERVICE_NAME), serviceName) + .put(table.getJsonField(table.SERVICE_TYPE), type())).setServiceType(this); + } + + } + +} diff --git a/core/installer/src/main/resources/ddl/01_ddl.sql b/edge/installer/model/src/main/resources/ddl/01_ddl.sql similarity index 59% rename from core/installer/src/main/resources/ddl/01_ddl.sql rename to edge/installer/model/src/main/resources/ddl/01_ddl.sql index 0c8b67ce3..ce84efea0 100644 --- a/core/installer/src/main/resources/ddl/01_ddl.sql +++ b/edge/installer/model/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/edge/installer/rule/build.gradle b/edge/installer/rule/build.gradle new file mode 100644 index 000000000..3103a7625 --- /dev/null +++ b/edge/installer/rule/build.gradle @@ -0,0 +1,3 @@ +dependencies { + compile project(':edge:installer:model') +} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/RequestedServiceData.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/dto/RequestedServiceData.java similarity index 69% rename from core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/RequestedServiceData.java rename to edge/installer/rule/src/main/java/com/nubeiot/edge/installer/dto/RequestedServiceData.java index bf1abbd80..5e0d1496e 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/RequestedServiceData.java +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/dto/RequestedServiceData.java @@ -1,4 +1,4 @@ -package com.nubeiot.edge.installer.model.dto; +package com.nubeiot.edge.installer.dto; import java.util.Map; import java.util.Objects; @@ -10,8 +10,11 @@ import com.nubeiot.core.NubeConfig.AppConfig; import com.nubeiot.core.dto.JsonData; +import lombok.AccessLevel; import lombok.Getter; +import lombok.experimental.FieldNameConstants; +@FieldNameConstants(level = AccessLevel.PRIVATE) public final class RequestedServiceData implements JsonData { @Getter @@ -25,8 +28,8 @@ public RequestedServiceData() { } @JsonCreator - public RequestedServiceData(@JsonProperty(value = "metadata") Map metadata, - @JsonProperty(value = "appConfig") AppConfig appConfig) { + public RequestedServiceData(@JsonProperty(value = Fields.metadata) Map metadata, + @JsonProperty(value = Fields.appConfig) AppConfig appConfig) { this.metadata = Objects.isNull(metadata) ? new JsonObject() : new JsonObject(metadata); this.appConfig = Objects.isNull(appConfig) ? new AppConfig() : appConfig; } diff --git a/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationParser.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationParser.java new file mode 100644 index 000000000..736b72e73 --- /dev/null +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationParser.java @@ -0,0 +1,22 @@ +package com.nubeiot.edge.installer.rule; + +import java.nio.file.Path; + +import com.nubeiot.edge.installer.dto.RequestedServiceData; +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; + +import lombok.NonNull; + +public interface ApplicationParser { + + static @NonNull ApplicationParser create(@NonNull Path dataDir) { + return new DefaultApplicationParser(dataDir); + } + + @NonNull Path dataDir(); + + @NonNull IApplication parse(@NonNull RuleRepository ruleRepository, @NonNull RequestedServiceData serviceData) + throws InvalidModuleType; + +} diff --git a/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationRule.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationRule.java new file mode 100644 index 000000000..13ed49687 --- /dev/null +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/ApplicationRule.java @@ -0,0 +1,33 @@ +package com.nubeiot.edge.installer.rule; + +import java.util.function.Function; +import java.util.function.Predicate; + +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.type.VertxModuleType.JVMModuleType; + +import lombok.NonNull; + +public interface ApplicationRule { + + @NonNull + static ApplicationRule create(@NonNull Function validation) { + return new DefaultApplicationRule(validation); + } + + static ApplicationRule jvmRule(@NonNull String... artifactGroups) { + final Predicate predicate = JVMModuleType.rulePredicate(artifactGroups); + return create(app -> { + if (!predicate.test(app.getAppId())) { + throw new InvalidModuleType("Unqualified whitelist " + app.getServiceType().type() + " artifact"); + } + return app; + }); + } + + @NonNull IApplication validate(@NonNull IApplication application) throws InvalidModuleType; + + @NonNull ApplicationRule andThen(ApplicationRule andThen); + +} diff --git a/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationParser.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationParser.java new file mode 100644 index 000000000..fa1ec510c --- /dev/null +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationParser.java @@ -0,0 +1,48 @@ +package com.nubeiot.edge.installer.rule; + +import java.nio.file.Path; +import java.util.Optional; + +import io.vertx.core.json.JsonObject; + +import com.nubeiot.core.NubeConfig; +import com.nubeiot.core.NubeConfig.AppConfig; +import com.nubeiot.core.utils.FileUtils; +import com.nubeiot.edge.installer.dto.RequestedServiceData; +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; +import com.nubeiot.edge.installer.model.type.ModuleType; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.experimental.Accessors; + +@Getter +@Accessors(fluent = true) +@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +final class DefaultApplicationParser implements ApplicationParser { + + private final Path dataDir; + + @Override + public @NonNull IApplication parse(@NonNull RuleRepository ruleRepository, + @NonNull RequestedServiceData serviceData) throws InvalidModuleType { + final IApplication application = parse(dataDir(), serviceData.getMetadata(), serviceData.getAppConfig()); + return Optional.ofNullable(ruleRepository.get(application.getServiceType())) + .map(r -> r.validate(application)) + .orElse(application); + } + + private IApplication parse(@NonNull Path dataDir, @NonNull JsonObject metadata, AppConfig appConfig) { + final IApplication application = ModuleType.factory(metadata.getString("service_type")).serialize(metadata); + return application.setAppConfig(appConfig.toJson()) + .setSystemConfig(computeAppSystemConfig(dataDir, application.getAppId())); + } + + private JsonObject computeAppSystemConfig(@NonNull Path parentDataDir, String serviceId) { + return NubeConfig.blank(FileUtils.recomputeDataDir(parentDataDir, FileUtils.normalize(serviceId))).toJson(); + } + +} diff --git a/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationRule.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationRule.java new file mode 100644 index 000000000..664a6a752 --- /dev/null +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/DefaultApplicationRule.java @@ -0,0 +1,33 @@ +package com.nubeiot.edge.installer.rule; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.interfaces.IApplication; + +import lombok.AccessLevel; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +final class DefaultApplicationRule implements ApplicationRule { + + @NonNull + private final Function validation; + private ApplicationRule andThen; + + @Override + public @NonNull IApplication validate(@NonNull IApplication application) throws InvalidModuleType { + final IApplication app = validation.apply(application); + return Optional.ofNullable(andThen).map(validator -> validator.validate(app)).orElse(app); + } + + @Override + public @NonNull ApplicationRule andThen(ApplicationRule andThen) { + this.andThen = Objects.isNull(this.andThen) ? andThen : this.andThen.andThen(andThen); + return this; + } + +} diff --git a/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/RuleRepository.java b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/RuleRepository.java new file mode 100644 index 000000000..76c64762a --- /dev/null +++ b/edge/installer/rule/src/main/java/com/nubeiot/edge/installer/rule/RuleRepository.java @@ -0,0 +1,37 @@ +package com.nubeiot.edge.installer.rule; + +import com.nubeiot.core.cache.AbstractLocalCache; +import com.nubeiot.core.cache.LocalDataCache; +import com.nubeiot.edge.installer.model.type.ModuleType; +import com.nubeiot.edge.installer.model.type.VertxModuleType; + +import lombok.NonNull; + +public final class RuleRepository extends AbstractLocalCache + implements LocalDataCache { + + public static RuleRepository createJVMRule(@NonNull String... artifactGroups) { + final ApplicationRule rule = ApplicationRule.jvmRule(artifactGroups); + return new RuleRepository().add(VertxModuleType.JAVA, rule) + .add(VertxModuleType.GROOVY, rule) + .add(VertxModuleType.KOTLIN, rule) + .add(VertxModuleType.SCALA, rule); + } + + @Override + protected @NonNull String keyLabel() { + return ModuleType.class.getName(); + } + + @Override + protected @NonNull String valueLabel() { + return ApplicationRule.class.getName(); + } + + @Override + public RuleRepository add(@NonNull ModuleType key, @NonNull ApplicationRule applicationRule) { + cache().put(key, applicationRule); + return this; + } + +} diff --git a/edge/installer/rule/src/test/java/com/nubeiot/edge/installer/rule/ApplicationRuleTest.java b/edge/installer/rule/src/test/java/com/nubeiot/edge/installer/rule/ApplicationRuleTest.java new file mode 100644 index 000000000..ee533d38f --- /dev/null +++ b/edge/installer/rule/src/test/java/com/nubeiot/edge/installer/rule/ApplicationRuleTest.java @@ -0,0 +1,38 @@ +package com.nubeiot.edge.installer.rule; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.edge.installer.model.InvalidModuleType; +import com.nubeiot.edge.installer.model.tables.pojos.Application; +import com.nubeiot.edge.installer.model.type.VertxModuleType; + +public class ApplicationRuleTest { + + @Test(expected = InvalidModuleType.class) + public void test_rule_invalid() { + final RuleRepository ruleRepository = RuleRepository.createJVMRule(""); + final Application application = new Application().setAppId(null).setServiceType(VertxModuleType.JAVA); + ruleRepository.get(VertxModuleType.JAVA).validate(application); + } + + @Test + public void test_jvm_rule_one_artifact_group() { + final RuleRepository repo = RuleRepository.createJVMRule("com.nubeio.test"); + final Application application = new Application().setAppId("com.nubeio.test.app"); + Assert.assertNotNull(repo.get(VertxModuleType.JAVA).validate(application)); + Assert.assertNotNull(repo.get(VertxModuleType.GROOVY).validate(application)); + Assert.assertNotNull(repo.get(VertxModuleType.KOTLIN).validate(application)); + Assert.assertNotNull(repo.get(VertxModuleType.SCALA).validate(application)); + } + + @Test + public void test_jvm_rule_many_artifact_groups() { + final RuleRepository repo = RuleRepository.createJVMRule("com.nubeio.test", "com.nubeio.hub"); + Assert.assertNotNull( + repo.get(VertxModuleType.JAVA).validate(new Application().setAppId("com.nubeio.test.app"))); + Assert.assertNotNull( + repo.get(VertxModuleType.KOTLIN).validate(new Application().setAppId("com.nubeio.hub.app"))); + } + +} diff --git a/edge/installer/service/build.gradle b/edge/installer/service/build.gradle new file mode 100644 index 000000000..915ad255f --- /dev/null +++ b/edge/installer/service/build.gradle @@ -0,0 +1,10 @@ +dependencies { + compile project(':core:auth') + compile project(':core:micro') + compile project(':core:archiver') + compile project(':edge:installer:model') + compile project(':edge:installer:rule') + compile "io.vertx:vertx-maven-service-factory:$project.versions.vertx" + + testCompile project(":core:base").sourceSets.test.output +} diff --git a/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerCacheInitializer.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerCacheInitializer.java new file mode 100644 index 000000000..f94fa78ee --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerCacheInitializer.java @@ -0,0 +1,32 @@ +package com.nubeiot.edge.installer; + +import io.vertx.core.Vertx; + +import com.nubeiot.core.IConfig; +import com.nubeiot.core.cache.CacheInitializer; + +import lombok.NonNull; + +public final class InstallerCacheInitializer implements CacheInitializer { + + public static final String INSTALLER_CFG = "INSTALLER_CFG"; + public static final String APP_DEPLOYER_CFG = "APP_DEPLOYER_CFG"; + public static final String RULE_REPOSITORY = "APPLICATION_RULE_REPOSITORY"; + + @Override + public InstallerCacheInitializer init(@NonNull InstallerVerticle context) { + final Vertx vertx = context.getVertx(); + addBlockingCache(vertx, INSTALLER_CFG, () -> getInstallerConfig(context), context::addSharedData); + addBlockingCache(vertx, APP_DEPLOYER_CFG, context::appDeployerDefinition, context::addSharedData); + addBlockingCache(vertx, RULE_REPOSITORY, context::ruleRepository, context::addSharedData); + return this; + } + + private InstallerConfig getInstallerConfig(@NonNull InstallerVerticle context) { + final InstallerConfig installerConfig = IConfig.from(context.getNubeConfig().getAppConfig(), + InstallerConfig.class); + installerConfig.getRepoConfig().recomputeLocal(context.getNubeConfig().getDataDir()); + return installerConfig; + } + +} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java similarity index 96% rename from core/installer/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java index ea841a005..664863c2c 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerConfig.java @@ -17,8 +17,8 @@ import com.nubeiot.core.NubeConfig.AppConfig; import com.nubeiot.core.utils.FileUtils; import com.nubeiot.core.utils.Strings; -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.dto.RequestedServiceData; +import com.nubeiot.edge.installer.dto.RequestedServiceData; +import com.nubeiot.edge.installer.model.type.ModuleType; import lombok.Getter; import lombok.Setter; diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java similarity index 55% rename from core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java index 3c005f130..891e4551f 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerEntityHandler.java @@ -1,8 +1,6 @@ package com.nubeiot.edge.installer; -import java.nio.file.Path; import java.time.OffsetDateTime; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -30,21 +28,23 @@ import com.nubeiot.core.sql.decorator.EntityConstraintHolder; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig; -import com.nubeiot.edge.installer.loader.ModuleTypeRule; +import com.nubeiot.edge.installer.dto.RequestedServiceData; import com.nubeiot.edge.installer.model.DefaultCatalog; +import com.nubeiot.edge.installer.model.InstallerApiIndex; 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.InstallerApiIndex; +import com.nubeiot.edge.installer.rule.ApplicationParser; +import com.nubeiot.edge.installer.rule.RuleRepository; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; +import com.nubeiot.edge.installer.service.InstallerAction; import lombok.AccessLevel; import lombok.Getter; @@ -53,9 +53,6 @@ public abstract class InstallerEntityHandler extends AbstractEntityHandler implements InstallerApiIndex, EntityConstraintHolder { - public static final String SHARED_MODULE_RULE = "MODULE_RULE"; - public static final String SHARED_INSTALLER_CFG = "INSTALLER_CFG"; - public static final String SHARED_APP_DEPLOYER_CFG = "APP_DEPLOYER_CFG"; @Getter(value = AccessLevel.PACKAGE) private EventAction bootstrap; @@ -70,7 +67,7 @@ protected InstallerEntityHandler(Configuration configuration, Vertx vertx) { @Override public final Single before() { - InstallerConfig installerCfg = sharedData(SHARED_INSTALLER_CFG); + InstallerConfig installerCfg = sharedData(InstallerCacheInitializer.INSTALLER_CFG); return super.before().map(handler -> { InstallerRepository.create(handler.vertx()).setup(installerCfg.getRepoConfig(), dataDir()); return handler; @@ -92,29 +89,28 @@ 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); + ((AppDeployerDefinition) sharedData(InstallerCacheInitializer.APP_DEPLOYER_CFG)).register(this); return this; } - protected AppConfig transformAppConfig(RepositoryConfig repoConfig, ITblModule tblModule, AppConfig appConfig) { + protected AppConfig transformAppConfig(RepositoryConfig repoConfig, IApplication application, AppConfig appConfig) { return appConfig; } - protected TblModule decorateModule(TblModule module) { + protected Application decorateApp(Application module) { final OffsetDateTime now = DateTimes.now(); return module.setCreatedAt(now).setModifiedAt(now); } @@ -124,25 +120,25 @@ Single addBuiltinApps(InstallerConfig config) { if (config.getBuiltinApps().isEmpty()) { return Single.just(new JsonObject().put("status", Status.SUCCESS)); } - final Path dataDir = dataDir(); 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)) + .map(serviceData -> createApplication(config.getRepoConfig(), serviceData)) + .map(this::decorateApp) + .toList() + .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) { - ModuleTypeRule rule = sharedData(SHARED_MODULE_RULE); - ITblModule tblModule = rule.parse(serviceData.getMetadata()); - AppConfig appConfig = transformAppConfig(repoConfig, tblModule, serviceData.getAppConfig()); - return (TblModule) rule.parse(dataDir, tblModule, appConfig).setState(State.NONE); + private Application createApplication(@NonNull RepositoryConfig repoConfig, + @NonNull RequestedServiceData serviceData) { + final RuleRepository repo = sharedData(InstallerCacheInitializer.RULE_REPOSITORY); + final IApplication application = ApplicationParser.create(dataDir()).parse(repo, serviceData); + final AppConfig appConfig = transformAppConfig(repoConfig, application, serviceData.getAppConfig()); + return (Application) application.setAppConfig(appConfig.toJson()).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,33 +150,34 @@ 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) { - if (transaction.getEvent() == EventAction.CREATE || transaction.getEvent() == EventAction.INIT) { + private Application checkingTransaction(Application module, DeployTransaction transaction) { + if (InstallerAction.isInstall(transaction.getEvent())) { return module.setState(State.ENABLED); } - if (transaction.getEvent() == EventAction.UPDATE || transaction.getEvent() == EventAction.PATCH) { + if (InstallerAction.isUpdate(transaction.getEvent())) { JsonObject prevMeta = transaction.getPrevMetadata(); 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 +187,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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java similarity index 93% rename from core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java index ea40c2d28..823a0c968 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerSchemaHandler.java @@ -15,14 +15,14 @@ final class InstallerSchemaHandler implements SchemaHandler { @Override public @NonNull Table table() { - return Tables.TBL_MODULE; + return Tables.APPLICATION; } @Override public @NonNull SchemaInitializer initializer() { return entityHandler -> { InstallerEntityHandler handler = (InstallerEntityHandler) entityHandler; - final InstallerConfig config = handler.sharedData(InstallerEntityHandler.SHARED_INSTALLER_CFG); + final InstallerConfig config = handler.sharedData(InstallerCacheInitializer.INSTALLER_CFG); return handler.addBuiltinApps(config); }; } diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java similarity index 82% rename from core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java index f96435aaa..e1b906d36 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/InstallerVerticle.java @@ -15,8 +15,8 @@ import com.nubeiot.core.micro.register.EventHttpServiceRegister; 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.rule.RuleRepository; +import com.nubeiot.edge.installer.service.AppDeployerDefinition; import com.nubeiot.edge.installer.service.AppDeploymentWorkflow; import com.nubeiot.edge.installer.service.InstallerService; @@ -37,11 +37,8 @@ public void start() { super.start(); final InstallerConfig installerConfig = IConfig.from(nubeConfig.getAppConfig(), InstallerConfig.class); installerConfig.getRepoConfig().recomputeLocal(nubeConfig.getDataDir()); - 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()) - .addProvider(new SqlProvider<>(entityHandlerClass()), this::sqlHandler) + new InstallerCacheInitializer().init(this); + this.addProvider(new SqlProvider<>(entityHandlerClass()), this::sqlHandler) .addProvider(new MicroserviceProvider(), ctx -> microContext = (MicroContext) ctx) .registerSuccessHandler(v -> publishApis(microContext).flatMap(r -> deployAppModules()).subscribe(r -> { logger.info("Trigger deploying {} app modules successfully", r.size()); @@ -55,10 +52,10 @@ public void start() { protected abstract Class entityHandlerClass(); @NonNull - protected abstract Supplier getModuleRuleProvider(); + protected abstract AppDeployerDefinition appDeployerDefinition(); @NonNull - protected abstract AppDeployer appDeployer(); + protected abstract RuleRepository ruleRepository(); @NonNull protected abstract Supplier> services(@NonNull InstallerEntityHandler handler); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PostDeploymentResult.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PostDeploymentResult.java similarity index 96% rename from core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PostDeploymentResult.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PostDeploymentResult.java index 1d8111990..685fe0cb1 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PostDeploymentResult.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PostDeploymentResult.java @@ -1,4 +1,4 @@ -package com.nubeiot.edge.installer.model.dto; +package com.nubeiot.edge.installer.dto; import java.util.Objects; @@ -23,7 +23,7 @@ @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonDeserialize(builder = PostDeploymentResult.Builder.class) -public class PostDeploymentResult implements JsonData { +public final class PostDeploymentResult implements JsonData { private String serviceId; private String transactionId; diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResult.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PreDeploymentResult.java similarity index 94% rename from core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResult.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PreDeploymentResult.java index e15c46fe5..80c7210a8 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResult.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/dto/PreDeploymentResult.java @@ -1,8 +1,9 @@ -package com.nubeiot.edge.installer.model.dto; +package com.nubeiot.edge.installer.dto; import java.nio.file.Path; import java.util.Map; import java.util.Objects; +import java.util.Optional; import io.vertx.core.json.JsonObject; import io.vertx.core.logging.Logger; @@ -98,7 +99,7 @@ public static class Builder { private JsonObject appConfig; private JsonObject systemConfig; - private Path dataDir = FileUtils.DEFAULT_DATADIR; + private Path dataDir; @JsonProperty("app_config") public Builder appConfig(Map appConfig) { @@ -131,7 +132,9 @@ public PreDeploymentResult build() { NubeConfig systemConfig = IConfig.parseConfig(this.systemConfig, NubeConfig.class, () -> NubeConfig.blank(this.systemConfig)); - systemConfig.setDataDir(FileUtils.recomputeDataDir(dataDir, FileUtils.normalize(serviceId))); + final Path dataDir = FileUtils.recomputeDataDir( + Optional.ofNullable(this.dataDir).orElse(FileUtils.DEFAULT_DATADIR), FileUtils.normalize(serviceId)); + systemConfig.setDataDir(dataDir); return new PreDeploymentResult(transactionId, action, Objects.isNull(prevState) ? State.NONE : prevState, Objects.isNull(targetState) ? State.NONE : targetState, serviceId, serviceFQN, deployId, appConfig, systemConfig, silent); diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java similarity index 88% rename from core/installer/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java index e5c7d090e..3a7d3731a 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/repository/InstallerRepository.java @@ -16,7 +16,8 @@ import com.nubeiot.core.utils.FileUtils; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig.RemoteRepositoryConfig; -import com.nubeiot.edge.installer.loader.ModuleType; +import com.nubeiot.edge.installer.model.type.ModuleType; +import com.nubeiot.edge.installer.model.type.VertxModuleType; import lombok.AccessLevel; import lombok.NonNull; @@ -37,7 +38,10 @@ public void setup(@NonNull RepositoryConfig repositoryCfg, @NonNull Path dataDir LOGGER.info("Setting up service local and remote repository"); RemoteRepositoryConfig remoteConfig = repositoryCfg.getRemoteConfig(); LOGGER.info("URLs" + remoteConfig.getUrls()); - remoteConfig.getUrls().entrySet().stream().parallel() + remoteConfig.getUrls() + .entrySet() + .stream() + .parallel() .forEach(entry -> handleVerticleFactory(dataDir, repositoryCfg.getLocal(), entry)); } @@ -47,9 +51,9 @@ private void handleVerticleFactory(@NonNull Path dataDir, String local, final String localDir = RepositoryConfig.DEFAULT_LOCAL.equals(local) ? dataDir.resolve(local).toString() : local; - if (ModuleType.JAVA == type) { + if (VertxModuleType.JAVA == type) { List externalServers = entry.getValue(); - String javaLocal = FileUtils.createFolder(localDir, type.name().toLowerCase(Locale.ENGLISH)); + String javaLocal = FileUtils.createFolder(localDir, type.type().toLowerCase(Locale.ENGLISH)); LOGGER.info("{} local repositories: {}", type, javaLocal); LOGGER.info("{} remote repositories: {}", type, externalServers); ResolverOptions resolver = new ResolverOptions().setRemoteRepositories( diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/search/IServiceSearch.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/IServiceSearch.java similarity index 100% rename from core/installer/src/main/java/com/nubeiot/edge/installer/search/IServiceSearch.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/IServiceSearch.java diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java similarity index 70% rename from core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java index 859ed5b84..8b748cf63 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/LocalServiceSearch.java @@ -27,10 +27,10 @@ import com.nubeiot.core.utils.DateTimes.Iso8601Parser; import com.nubeiot.core.utils.Strings; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.loader.ModuleType; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; 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 com.nubeiot.edge.installer.model.type.VertxModuleType; import lombok.NonNull; @@ -45,30 +45,28 @@ public LocalServiceSearch(@NonNull InstallerEntityHandler entityHandler) { } @Override - public Single search(RequestData requestData) throws NubeException { - logger.info("Start executing local service searching {}", requestData.filter()); + public Single search(@NonNull RequestData reqData) throws NubeException { + logger.info("Start executing local service searching {}", reqData.filter()); return this.entityHandler.genericQuery() - .executeAny( - context -> filter(validateFilter(requestData.filter()), requestData.pagination(), - context)) + .executeAny(ctx -> filter(validateFilter(reqData.filter()), reqData.pagination(), ctx)) .flattenAsObservable(records -> records) .flatMapSingle(this::excludeData) .collect(JsonArray::new, JsonArray::add) .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 +85,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(VertxModuleType.JAVA)); + Set fieldNames = Arrays.stream(Tables.APPLICATION.fields()) .map(Field::getName) .collect(Collectors.toSet()); filter.getMap() @@ -99,22 +97,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/search/RemoteServiceSearch.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/RemoteServiceSearch.java similarity index 100% rename from core/installer/src/main/java/com/nubeiot/edge/installer/search/RemoteServiceSearch.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/search/RemoteServiceSearch.java diff --git a/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java new file mode 100644 index 000000000..b602194b4 --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeployerDefinition.java @@ -0,0 +1,111 @@ +package com.nubeiot.edge.installer.service; + +import io.vertx.core.shareddata.Shareable; + +import com.nubeiot.core.event.EventAction; +import com.nubeiot.core.event.EventModel; +import com.nubeiot.core.event.EventPattern; +import com.nubeiot.edge.installer.InstallerEntityHandler; + +import lombok.NonNull; + +/** + * Application service deployer definition + * + * @since 1.0.0 + */ +public interface AppDeployerDefinition extends Shareable { + + static AppDeployerDefinition create(@NonNull String app) { + return create(AppDeployerDefinition.createExecuterAddr(app), AppDeployerDefinition.createSupervisorAddr(app), + AppDeployerDefinition.createReporterAddr(app)); + } + + /** + * Create app deployer definition. + * + * @param executerAddress the executer event + * @param supervisorAddress the supervisor event + * @param reporterAddress the reporter event + * @return the app deployer + * @since 1.0.0 + */ + static AppDeployerDefinition create(@NonNull String executerAddress, @NonNull String supervisorAddress, + @NonNull String reporterAddress) { + return new DefaultAppDeployerDefinition(executerAddress, supervisorAddress, reporterAddress); + } + + static String createExecuterAddr(String app) { + return AppDeployerDefinition.class.getPackage().getName() + "." + app + ".deployment.executer"; + } + + static String createSupervisorAddr(String app) { + return AppDeployerDefinition.class.getPackage().getName() + "." + app + ".deployment.supervisor"; + } + + static String createReporterAddr(String app) { + return AppDeployerDefinition.class.getPackage().getName() + "." + app + ".deployment.reporter"; + } + + static EventModel createExecuterEvent(@NonNull String address) { + return EventModel.builder() + .address(address) + .pattern(EventPattern.POINT_2_POINT) + .local(true) + .addEvents(EventAction.INIT, EventAction.CREATE, EventAction.UPDATE, EventAction.PATCH, + EventAction.REMOVE) + .build(); + } + + static EventModel createReporterEvent(@NonNull String address) { + return EventModel.builder() + .address(address) + .pattern(EventPattern.POINT_2_POINT) + .local(true) + .event(EventAction.NOTIFY) + .build(); + } + + static EventModel createSupervisorEvent(@NonNull String address) { + return EventModel.builder() + .address(address) + .pattern(EventPattern.POINT_2_POINT) + .local(true) + .event(EventAction.MONITOR) + .build(); + } + + /** + * Defines executer event + * + * @return executer event + * @since 1.0.0 + */ + @NonNull EventModel getExecuterEvent(); + + /** + * Defines supervisor event after deployed application physically and in charge of updating database + * + * @return supervisor event + * @since 1.0.0 + */ + @NonNull EventModel getSupervisorEvent(); + + /** + * Defines reporter event after deployed and updated database completely + * + * @return reporter event + * @since 1.0.0 + */ + @NonNull EventModel getReporterEvent(); + + /** + * Register event service + * + * @param entityHandler Entity handler + * @return a reference to this, so the API can be used fluently + * @since 1.0.0 + */ + @NonNull AppDeployerDefinition register(@NonNull InstallerEntityHandler entityHandler); + +} diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentExecuter.java similarity index 82% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentExecuter.java index fe39c5293..6f481ac45 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentService.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentExecuter.java @@ -1,9 +1,10 @@ package com.nubeiot.edge.installer.service; -import java.util.Arrays; import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import io.vertx.core.AsyncResult; import io.vertx.core.DeploymentOptions; @@ -25,23 +26,24 @@ import com.nubeiot.core.event.EventbusClient; import com.nubeiot.core.exceptions.EngineException; import com.nubeiot.core.exceptions.ErrorMessage; +import com.nubeiot.edge.installer.InstallerCacheInitializer; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.dto.PostDeploymentResult; -import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; +import com.nubeiot.edge.installer.dto.PostDeploymentResult; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; import lombok.NonNull; -class AppDeploymentService implements DeploymentService { +class AppDeploymentExecuter implements DeploymentService { - private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentService.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentExecuter.class); private final Vertx vertx; private final Function sharedDataFunc; private final WorkerExecutor worker; - AppDeploymentService(@NonNull InstallerEntityHandler entityHandler) { + AppDeploymentExecuter(@NonNull InstallerEntityHandler entityHandler) { this.vertx = entityHandler.vertx(); this.sharedDataFunc = entityHandler::sharedData; - this.worker = vertx.createSharedWorkerExecutor("installer", 1, 3, TimeUnit.MINUTES); + this.worker = vertx.createSharedWorkerExecutor("installer", 2, 3, TimeUnit.MINUTES); } @EventContractor(action = {EventAction.CREATE, EventAction.INIT}) @@ -63,7 +65,7 @@ public JsonObject remove(RequestData data) { return new JsonObject(); } - @EventContractor(action = {EventAction.UPDATE, EventAction.PATCH}) + @EventContractor(action = {EventAction.UPDATE, EventAction.MIGRATE, EventAction.PATCH}) public JsonObject reload(RequestData data) { PreDeploymentResult preResult = JsonData.from(data.body(), PreDeploymentResult.class); if (preResult.getTargetState() == State.DISABLED) { @@ -77,8 +79,9 @@ public JsonObject reload(RequestData data) { @Override public @NonNull Collection getAvailableEvents() { - return Arrays.asList(EventAction.INIT, EventAction.CREATE, EventAction.UPDATE, EventAction.HALT, - EventAction.PATCH, EventAction.REMOVE); + return Stream.of(InstallerAction.install(), InstallerAction.update(), InstallerAction.uninstall()) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); } void doDeploy(PreDeploymentResult preResult, Future future) { @@ -104,10 +107,10 @@ 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(InstallerCacheInitializer.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()))); + client.fire(DeliveryEvent.from(deployer.getSupervisorEvent(), new JsonObject().put("result", pr.toJson()))); } @Override diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentFinisher.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentReporter.java similarity index 88% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentFinisher.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentReporter.java index 2d9299469..845d1ed16 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentFinisher.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentReporter.java @@ -10,16 +10,16 @@ import com.nubeiot.core.event.EventContractor; import com.nubeiot.core.event.EventContractor.Param; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.dto.PostDeploymentResult; +import com.nubeiot.edge.installer.dto.PostDeploymentResult; import lombok.AccessLevel; import lombok.NonNull; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor(access = AccessLevel.PACKAGE) -class AppDeploymentFinisher implements DeploymentService { +class AppDeploymentReporter implements DeploymentService { - private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentFinisher.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentReporter.class); private final InstallerEntityHandler entityHandler; @Override diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentSupervisor.java similarity index 58% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentSupervisor.java index c009a7b8c..22ae6a575 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentTracker.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentSupervisor.java @@ -16,7 +16,6 @@ import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; -import com.nubeiot.core.component.SharedDataDelegate; import com.nubeiot.core.enums.State; import com.nubeiot.core.enums.Status; import com.nubeiot.core.event.DeliveryEvent; @@ -26,24 +25,25 @@ import com.nubeiot.core.event.EventbusClient; import com.nubeiot.core.statemachine.StateMachine; import com.nubeiot.core.utils.DateTimes; +import com.nubeiot.edge.installer.InstallerCacheInitializer; import com.nubeiot.edge.installer.InstallerEntityHandler; +import com.nubeiot.edge.installer.dto.PostDeploymentResult; 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; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor(access = AccessLevel.PACKAGE) -class AppDeploymentTracker implements DeploymentService { +class AppDeploymentSupervisor implements DeploymentService { - private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentTracker.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AppDeploymentSupervisor.class); private final InstallerEntityHandler entityHandler; @Override @@ -56,10 +56,10 @@ public Single handle(@Param("result") PostDeploymentResult Single last = Status.FAILED == result.getStatus() ? handleError(result) : handleSuccess(result); - final EventbusClient client = sharedData(SharedDataDelegate.SHARED_EVENTBUS); - final AppDeployer deployer = sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); + final EventbusClient client = entityHandler.eventClient(); + final AppDeployerDefinition deployer = sharedData(InstallerCacheInitializer.APP_DEPLOYER_CFG); return last.doOnSuccess(res -> client.fire( - DeliveryEvent.from(deployer.getFinisherEvent(), new JsonObject().put("result", res.toJson())))); + DeliveryEvent.from(deployer.getReporterEvent(), new JsonObject().put("result", res.toJson())))); } private Single handleSuccess(@NonNull PostDeploymentResult res) { @@ -68,23 +68,23 @@ 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)) + .flatMap(r1 -> queryExecutor.executeAny(c -> updateAppState(c, serviceId, state, v)) .map(r2 -> r1 + r2)) .map(records -> PostDeploymentResult.from(res, state, records)); } @@ -92,48 +92,41 @@ 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)) + .flatMap(r1 -> query.executeAny(c -> updateAppState(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()) + private int updateAppState(DSLContext context, String serviceId, State state, Map values) { + 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()); - if (Objects.isNull(history.getIssuedAt())) { - history.setIssuedAt(DateTimes.now()); - } - if (Objects.isNull(history.getModifiedAt())) { - history.setModifiedAt(DateTimes.now()); - } - if (Objects.isNull(history.getRetry())) { - history.setRetry(0); - } - return history; + private IApplicationHistory convertToHistory(IDeployTransaction transaction) { + IApplicationHistory history = new ApplicationHistory().fromJson(transaction.toJson()); + return history.setIssuedAt(Optional.ofNullable(history.getIssuedAt()).orElseGet(DateTimes::now)) + .setModifiedAt(Optional.ofNullable(history.getModifiedAt()).orElseGet(DateTimes::now)) + .setRetry(Optional.ofNullable(history.getRetry()).orElse(0)); } @Override diff --git a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java similarity index 53% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java index a926ddbc4..4eb7b65e9 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/AppDeploymentWorkflow.java @@ -24,12 +24,13 @@ import com.nubeiot.core.statemachine.StateMachine; import com.nubeiot.core.utils.DateTimes; import com.nubeiot.core.utils.Strings; +import com.nubeiot.edge.installer.InstallerCacheInitializer; 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.dto.PreDeploymentResult; +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,31 +39,32 @@ 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) { + public AppDeploymentWorkflow(@NonNull InstallerEntityHandler entityHandler) { this.entityHandler = entityHandler; - this.deployer = entityHandler.sharedData(InstallerEntityHandler.SHARED_APP_DEPLOYER_CFG); + this.definition = entityHandler.sharedData(InstallerCacheInitializer.APP_DEPLOYER_CFG); } - public Single process(ITblModule module, EventAction action) { - return process(Collections.singleton(module), action).firstOrError(); + public Single process(@NonNull IApplication application, @NonNull EventAction action) { + return process(Collections.singleton(application), action).firstOrError(); } - public Observable process(Collection modules, EventAction action) { - return Observable.fromIterable(modules).flatMapSingle(module -> processDeployment(module, action)); + public Observable process(@NonNull Collection applications, + @NonNull EventAction action) { + return Observable.fromIterable(applications).flatMapSingle(module -> processDeployment(module, action)); } - private Single processDeployment(ITblModule module, EventAction action) { - LOGGER.info("INSTALLER handle for {}::::{}", action, module.getServiceId()); - return createPreDeployment(module, action).doOnSuccess(this::deployModule).map(PreDeploymentResult::toResponse); + private Single processDeployment(IApplication application, EventAction action) { + LOGGER.info("INSTALLER handle for {}::::{}", action, application.getAppId()); + return createPreDeployment(application, action).doOnSuccess(this::deployModule) + .map(PreDeploymentResult::toResponse); } - private Single createPreDeployment(ITblModule req, EventAction action) { - LOGGER.info("INSTALLER create pre-deployment for {}::::{}", action, req.getServiceId()); - InstallerConfig config = entityHandler.sharedData(InstallerEntityHandler.SHARED_INSTALLER_CFG); - if (EventAction.CREATE == action || EventAction.INIT == action || - (EventAction.MIGRATE == action && State.PENDING == req.getState())) { + private Single createPreDeployment(IApplication req, EventAction action) { + LOGGER.info("INSTALLER create pre-deployment for {}::::{}", action, req.getAppId()); + InstallerConfig config = entityHandler.sharedData(InstallerCacheInitializer.INSTALLER_CFG); + if (EventAction.CREATE == action || InstallerAction.isInternal(action) && State.PENDING == req.getState()) { req.setState(State.ENABLED); } if (EventAction.REMOVE == action) { @@ -75,22 +77,23 @@ 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(); - if (EventAction.CREATE == action) { + Maybe into = Maybe.empty(); + if (InstallerAction.isInstall(action)) { into = Maybe.fromSingle(markModuleInsert(cloneDb)); } - if (EventAction.INIT == action || EventAction.UPDATE == action || EventAction.MIGRATE == action) { + if (InstallerAction.isUpdate(action) && !InstallerAction.isPatch(action)) { into = Maybe.fromSingle(markModuleModify(request, cloneDb, true)); } - if (EventAction.PATCH == action) { + if (InstallerAction.isPatch(action)) { into = Maybe.fromSingle(markModuleModify(request, cloneDb, false)); } - if (EventAction.REMOVE == action) { + if (InstallerAction.isUninstall(action)) { into = Maybe.fromSingle(markModuleDelete(cloneDb)); } return into.switchIfEmpty(Single.error(new UnsupportedOperationException("Unsupported event " + action))) @@ -103,36 +106,35 @@ 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.getExecuterEvent(), action, preDeployResult.toRequestData())); } - private PreDeploymentResult createPreDeployResult(ITblModule module, String transactionId, EventAction action, + private PreDeploymentResult createPreDeployResult(IApplication app, String transactionId, EventAction action, State prevState, State targetState) { return PreDeploymentResult.builder() .transactionId(transactionId) - .action(action == EventAction.MIGRATE ? EventAction.UPDATE : action) + .action(action) .prevState(prevState) .targetState(targetState) - .serviceId(module.getServiceId()) - .serviceFQN(module.getServiceType() - .generateFQN(module.getServiceId(), module.getVersion(), - module.getServiceName())) - .deployId(module.getDeployId()) - .appConfig(module.getAppConfig()) - .systemConfig(module.getSystemConfig()) + .serviceId(app.getAppId()) + .serviceFQN(app.getServiceType() + .generateFQN(app.getAppId(), app.getVersion(), app.getServiceName())) + .deployId(app.getDeployId()) + .appConfig(app.getAppConfig()) + .systemConfig(app.getSystemConfig()) .dataDir(entityHandler.dataDir().toString()) .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,51 +144,51 @@ 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 app) { + LOGGER.debug("INSTALLER mark service {} to create...", app.getAppId()); OffsetDateTime now = DateTimes.now(); - return entityHandler.moduleDao() - .insert((TblModule) module.setCreatedAt(now).setModifiedAt(now).setState(State.PENDING)) - .map(i -> module); + return entityHandler.applicationDao() + .insert((Application) app.setCreatedAt(now).setModifiedAt(now).setState(State.PENDING)) + .map(i -> app); } - 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"); } if (Objects.isNull(newOne.getState()) && isUpdated) { throw new IllegalArgumentException("Service state is mandatory"); } - old.setVersion(Strings.isBlank(newOne.getVersion()) ? old.getVersion() : newOne.getVersion()); - old.setPublishedBy(Strings.isBlank(newOne.getPublishedBy()) ? old.getPublishedBy() : newOne.getPublishedBy()); + old.setVersion(Strings.fallback(newOne.getVersion(), old.getVersion())); + old.setPublishedBy(Strings.fallback(newOne.getPublishedBy(), old.getPublishedBy())); old.setState(Objects.isNull(newOne.getState()) ? old.getState() : newOne.getState()); old.setSystemConfig( IConfig.merge(old.getSystemConfig(), newOne.getSystemConfig(), isUpdated, NubeConfig.class).toJson()); @@ -194,15 +196,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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java similarity index 59% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/ModuleService.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java index 2272aed4e..cc5077a93 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/ModuleService.java +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/ApplicationService.java @@ -8,18 +8,20 @@ import com.nubeiot.core.dto.JsonData; import com.nubeiot.core.dto.RequestData; +import com.nubeiot.core.dto.RequestFilter; import com.nubeiot.core.event.EventAction; import com.nubeiot.core.event.EventContractor; import com.nubeiot.core.exceptions.NotFoundException; import com.nubeiot.core.http.base.event.ActionMethodMapping; import com.nubeiot.core.utils.Strings; +import com.nubeiot.edge.installer.InstallerCacheInitializer; import com.nubeiot.edge.installer.InstallerEntityHandler; -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.dto.PreDeploymentResult; +import com.nubeiot.edge.installer.dto.RequestedServiceData; +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.rule.ApplicationParser; import com.nubeiot.edge.installer.search.LocalServiceSearch; import lombok.AccessLevel; @@ -27,7 +29,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 +39,7 @@ public final String servicePath() { } public final String paramPath() { - return "service_id"; + return "app_id"; } @Override @@ -46,21 +48,22 @@ public final String paramPath() { } @EventContractor(action = EventAction.GET_LIST, returnType = Single.class) - public Single getList(RequestData data) { - JsonObject filter = data.filter(); - if (filter.getBoolean("available", Boolean.FALSE)) { + public Single list(RequestData data) { + RequestFilter filter = data.filter(); + if (filter.parseBoolean("_available")) { return Single.just(new JsonObject()); } return new LocalServiceSearch(entityHandler).search(data); } @EventContractor(action = EventAction.GET_ONE, returnType = Single.class) - public Single getOne(RequestData data) { + public Single get(RequestData data) { String serviceId = data.body().getString(paramPath()); 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,29 +73,29 @@ 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 app = createApplication(data.body()); + if (Strings.isBlank(app.getAppId())) { throw new IllegalArgumentException("Service id is mandatory"); } - return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.PATCH); + return new AppDeploymentWorkflow(entityHandler).process(app, EventAction.PATCH); } @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 app = validate(data.body()); + if (Strings.isBlank(app.getServiceName()) && Strings.isBlank(app.getAppId())) { throw new IllegalArgumentException("Provide at least service id or service name"); } - return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.UPDATE); + return new AppDeploymentWorkflow(entityHandler).process(app, EventAction.UPDATE); } @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 app = new Application().setAppId(data.body().getString(paramPath())); + if (Strings.isBlank(app.getAppId())) { throw new IllegalArgumentException("Service id is mandatory"); } - return new AppDeploymentWorkflow(entityHandler).process(module, EventAction.REMOVE); + return new AppDeploymentWorkflow(entityHandler).process(app, EventAction.REMOVE); } @EventContractor(action = EventAction.CREATE, returnType = Single.class) @@ -100,33 +103,33 @@ 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); - if (Strings.isBlank(module.getServiceName())) { + private IApplication validate(@NonNull JsonObject body) { + IApplication application = createApplication(body); + if (Strings.isBlank(application.getServiceName())) { throw new IllegalArgumentException("Service name is mandatory"); } - if (Strings.isBlank(module.getVersion())) { + if (Strings.isBlank(application.getVersion())) { throw new IllegalArgumentException("Service version is mandatory"); } - return module; + return application; } - private ITblModule createTblModule(JsonObject body) { - String serviceId = body.getString(paramPath()); + private IApplication createApplication(JsonObject body) { + String appId = body.getString(paramPath()); body.remove(paramPath()); - RequestedServiceData serviceData = body.isEmpty() - ? new RequestedServiceData() - : JsonData.from(body, RequestedServiceData.class); - if (Strings.isNotBlank(serviceId)) { - serviceData.getMetadata().put(paramPath(), serviceId); + RequestedServiceData data = body.isEmpty() + ? new RequestedServiceData() + : JsonData.from(body, RequestedServiceData.class); + if (Strings.isNotBlank(appId)) { + data.getMetadata().put(paramPath(), appId); } - final ModuleTypeRule rule = entityHandler.sharedData(InstallerEntityHandler.SHARED_MODULE_RULE); - return rule.parse(entityHandler.dataDir(), serviceData.getMetadata(), serviceData.getAppConfig()); + return ApplicationParser.create(entityHandler.dataDir()) + .parse(entityHandler.sharedData(InstallerCacheInitializer.RULE_REPOSITORY), data); } } diff --git a/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/BackupByAppService.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/BackupByAppService.java new file mode 100644 index 000000000..3fc12230f --- /dev/null +++ b/edge/installer/service/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.InstallerApiIndex.ApplicationMetadata; +import com.nubeiot.edge.installer.model.InstallerApiIndex.BackupMetadata; +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 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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java new file mode 100644 index 000000000..d9a7ca799 --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DefaultAppDeployerDefinition.java @@ -0,0 +1,35 @@ +package com.nubeiot.edge.installer.service; + +import com.nubeiot.core.event.EventModel; +import com.nubeiot.edge.installer.InstallerEntityHandler; + +import lombok.Getter; +import lombok.NonNull; + +@Getter +final class DefaultAppDeployerDefinition implements AppDeployerDefinition { + + @NonNull + private final EventModel executerEvent; + @NonNull + private final EventModel supervisorEvent; + @NonNull + private final EventModel reporterEvent; + + public DefaultAppDeployerDefinition(@NonNull String executerAddress, @NonNull String supervisorAddress, + @NonNull String reporterAddress) { + this.executerEvent = AppDeployerDefinition.createExecuterEvent(executerAddress); + this.supervisorEvent = AppDeployerDefinition.createSupervisorEvent(supervisorAddress); + this.reporterEvent = AppDeployerDefinition.createReporterEvent(reporterAddress); + } + + @Override + public AppDeployerDefinition register(@NonNull InstallerEntityHandler entityHandler) { + entityHandler.eventClient() + .register(executerEvent, new AppDeploymentExecuter(entityHandler)) + .register(supervisorEvent, new AppDeploymentSupervisor(entityHandler)) + .register(reporterEvent, new AppDeploymentReporter(entityHandler)); + return this; + } + +} diff --git a/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java new file mode 100644 index 000000000..1fcf1e98a --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/DeploymentService.java @@ -0,0 +1,22 @@ +package com.nubeiot.edge.installer.service; + +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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerAction.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerAction.java new file mode 100644 index 000000000..647b60a0e --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerAction.java @@ -0,0 +1,50 @@ +package com.nubeiot.edge.installer.service; + +import java.util.Arrays; +import java.util.Collection; + +import com.nubeiot.core.event.EventAction; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class InstallerAction { + + public static Collection install() { + return Arrays.asList(EventAction.INIT, EventAction.CREATE); + } + + public static Collection update() { + return Arrays.asList(EventAction.MIGRATE, EventAction.UPDATE, EventAction.PATCH); + } + + public static Collection uninstall() { + return Arrays.asList(EventAction.REMOVE, EventAction.HALT); + } + + public static Collection internal() { + return Arrays.asList(EventAction.INIT, EventAction.MIGRATE); + } + + public static boolean isInstall(EventAction action) { + return install().contains(action); + } + + public static boolean isUpdate(EventAction action) { + return update().contains(action); + } + + public static boolean isPatch(EventAction action) { + return update().contains(action); + } + + public static boolean isUninstall(EventAction action) { + return uninstall().contains(action); + } + + public static boolean isInternal(EventAction action) { + return internal().contains(action); + } + +} diff --git a/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java new file mode 100644 index 000000000..ae62347f9 --- /dev/null +++ b/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/InstallerService.java @@ -0,0 +1,93 @@ +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 com.nubeiot.core.http.base.EventHttpService; +import com.nubeiot.core.http.base.Urls; +import com.nubeiot.core.http.base.event.ActionMethodMapping; +import com.nubeiot.core.http.base.event.EventMethodDefinition; +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); + return ReflectionClass.stream(serviceClazz.getPackage().getName(), serviceClazz, ReflectionClass.publicClass()) + .map(clazz -> ReflectionClass.createObject(clazz, inputs)) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + + /** + * Defines Root path. + * + * @return Root path + * @since 1.0.0 + */ + default String rootPath() { + return "/installer"; + } + + /** + * 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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/TransactionByAppService.java similarity index 72% rename from edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByModuleService.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/TransactionByAppService.java index 0ec6e39a9..a2f86b5db 100644 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/service/EdgeTransactionByModuleService.java +++ b/edge/installer/service/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())) { + public Single list(RequestData data) { + 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/edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java similarity index 64% rename from core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java rename to edge/installer/service/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java index 4c686b8f1..6be184db8 100644 --- a/core/installer/src/main/java/com/nubeiot/edge/installer/service/TransactionService.java +++ b/edge/installer/service/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 get(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/test/java/com/nubeiot/edge/installer/BaseInstallerVerticleTest.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/BaseInstallerVerticleTest.java similarity index 100% rename from core/installer/src/test/java/com/nubeiot/edge/installer/BaseInstallerVerticleTest.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/BaseInstallerVerticleTest.java diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java similarity index 92% rename from core/installer/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java index 7e40dd0ba..077c21bdd 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java +++ b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/InstallerConfigTest.java @@ -15,8 +15,9 @@ import com.nubeiot.core.IConfig; import com.nubeiot.core.TestHelper.OSHelper; import com.nubeiot.edge.installer.InstallerConfig.RepositoryConfig.RemoteRepositoryConfig; -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.model.dto.RequestedServiceData; +import com.nubeiot.edge.installer.dto.RequestedServiceData; +import com.nubeiot.edge.installer.model.type.ModuleType; +import com.nubeiot.edge.installer.model.type.VertxModuleType; public class InstallerConfigTest { @@ -33,7 +34,7 @@ public void test_serialize_default() { InstallerConfig installerConfig = new InstallerConfig(); RemoteRepositoryConfig remoteConfig = installerConfig.getRepoConfig().getRemoteConfig(); remoteConfig.setCredential(new BasicCredential(CredentialType.BASIC, "user", "password")); - remoteConfig.addUrl(ModuleType.JAVA, new ExternalServer("abc")); + remoteConfig.addUrl(VertxModuleType.JAVA, new ExternalServer("abc")); Assert.assertTrue(installerConfig.getBuiltinApps().isEmpty()); JsonObject jsonObject = installerConfig.toJson(); System.out.println(jsonObject.encodePrettily()); @@ -67,7 +68,7 @@ public void test_parse_default() { Assert.assertEquals("password", ((BasicCredential) credential).getPassword()); Map> urls = installerConfig.getRepoConfig().getRemoteConfig().getUrls(); - List externalServers = urls.get(ModuleType.JAVA); + List externalServers = urls.get(VertxModuleType.JAVA); Assert.assertEquals(2, externalServers.size()); Assert.assertEquals("abc", externalServers.get(0).getUrl()); Assert.assertNull(externalServers.get(0).getCredential()); diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResultTest.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/dto/PreDeploymentResultTest.java similarity index 99% rename from core/installer/src/test/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResultTest.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/dto/PreDeploymentResultTest.java index fecff963b..8b291ce98 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/model/dto/PreDeploymentResultTest.java +++ b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/dto/PreDeploymentResultTest.java @@ -1,4 +1,4 @@ -package com.nubeiot.edge.installer.model.dto; +package com.nubeiot.edge.installer.dto; import static com.nubeiot.core.NubeConfig.create; diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerEntityHandler.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerEntityHandler.java similarity index 100% rename from core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerEntityHandler.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerEntityHandler.java diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java similarity index 70% rename from core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerService.java rename to edge/installer/service/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/edge/installer/service/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/edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java similarity index 63% rename from core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java index 2e0a07ce0..b0390db31 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java +++ b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/mock/MockInstallerVerticle.java @@ -1,6 +1,5 @@ package com.nubeiot.edge.installer.mock; -import java.util.Collections; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -8,11 +7,12 @@ import com.nubeiot.edge.installer.InstallerEntityHandler; 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.model.type.VertxModuleType; +import com.nubeiot.edge.installer.rule.ApplicationRule; +import com.nubeiot.edge.installer.rule.RuleRepository; +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 @@ -32,19 +32,17 @@ public class MockInstallerVerticle extends InstallerVerticle { } @Override - protected @NonNull Supplier getModuleRuleProvider() { - return () -> new ModuleTypeRule().registerRule(ModuleType.JAVA, - Collections.singletonList("com.nubeiot.edge.module")); + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return definition; } - @Override - protected @NonNull AppDeployer appDeployer() { - return appDeployer; + protected @NonNull RuleRepository ruleRepository() { + return new RuleRepository().add(VertxModuleType.JAVA, ApplicationRule.jvmRule("com.nubeiot.edge.mock")); } @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/search/LocalServiceSearchTest.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/search/LocalServiceSearchTest.java similarity index 100% rename from core/installer/src/test/java/com/nubeiot/edge/installer/search/LocalServiceSearchTest.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/search/LocalServiceSearchTest.java diff --git a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentExecuter.java similarity index 74% rename from core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentExecuter.java index be2971012..0c8c20b8a 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentService.java +++ b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockDeploymentExecuter.java @@ -5,17 +5,17 @@ import io.vertx.core.Future; import com.nubeiot.edge.installer.InstallerEntityHandler; -import com.nubeiot.edge.installer.model.dto.PreDeploymentResult; +import com.nubeiot.edge.installer.dto.PreDeploymentResult; import lombok.NonNull; //TODO extends this for success/failed/timeout case and assert PreDeploymentResult -public class MockDeploymentService extends AppDeploymentService { +public class MockDeploymentExecuter extends AppDeploymentExecuter { @NonNull private final UUID mockDeployId; - MockDeploymentService(@NonNull InstallerEntityHandler entityHandler, @NonNull UUID mockDeployId) { + protected MockDeploymentExecuter(@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/edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockReporterService.java similarity index 62% rename from core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java rename to edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockReporterService.java index be8f54caa..1ab8d17b6 100644 --- a/core/installer/src/test/java/com/nubeiot/edge/installer/service/MockFinisherService.java +++ b/edge/installer/service/src/test/java/com/nubeiot/edge/installer/service/MockReporterService.java @@ -3,9 +3,9 @@ import com.nubeiot.edge.installer.InstallerEntityHandler; //TODO extends this for success/failed/timeout case and assert PostDeploymentResult -public class MockFinisherService extends AppDeploymentFinisher { +public class MockReporterService extends AppDeploymentReporter { - MockFinisherService(InstallerEntityHandler entityHandler) { + protected MockReporterService(InstallerEntityHandler entityHandler) { super(entityHandler); } diff --git a/core/installer/src/test/resources/mock-installer.json b/edge/installer/service/src/test/resources/mock-installer.json similarity index 100% rename from core/installer/src/test/resources/mock-installer.json rename to edge/installer/service/src/test/resources/mock-installer.json diff --git a/edge/module/datapoint/src/main/java/com/nubeiot/edge/module/datapoint/cache/DataCacheInitializer.java b/edge/module/datapoint/src/main/java/com/nubeiot/edge/module/datapoint/cache/DataCacheInitializer.java index e42e06af9..956622236 100644 --- a/edge/module/datapoint/src/main/java/com/nubeiot/edge/module/datapoint/cache/DataCacheInitializer.java +++ b/edge/module/datapoint/src/main/java/com/nubeiot/edge/module/datapoint/cache/DataCacheInitializer.java @@ -1,7 +1,5 @@ package com.nubeiot.edge.module.datapoint.cache; -import java.util.function.Supplier; - import com.fasterxml.jackson.databind.InjectableValues.Std; import com.nubeiot.core.cache.CacheInitializer; import com.nubeiot.core.cache.ClassGraphCache; @@ -23,20 +21,16 @@ public final class DataCacheInitializer implements CacheInitializer jobDefinitionCache = new ClassGraphCache<>("Scheduler Job"); DataJobDefinition.MAPPER.setInjectableValues(new Std().addValue(JOB_CONFIG_CACHE, jobDefinitionCache)); - addBlockingCache(context, EntityServiceIndex.DATA_KEY, EntityServiceCacheIndex::create); - addBlockingCache(context, JOB_CONFIG_CACHE, () -> jobDefinitionCache.register(DataJobDefinition::find)); - addBlockingCache(context, HISTORIES_DATA_CACHE, PointHistoryCache::new); - addBlockingCache(context, PROTOCOL_DISPATCHER_CACHE, () -> ProtocolDispatcherCache.init(context)); + addBlockingCache(context.vertx(), EntityServiceIndex.DATA_KEY, EntityServiceCacheIndex::create, + context::addSharedData); + addBlockingCache(context.vertx(), JOB_CONFIG_CACHE, () -> jobDefinitionCache.register(DataJobDefinition::find), + context::addSharedData); + addBlockingCache(context.vertx(), HISTORIES_DATA_CACHE, PointHistoryCache::new, context::addSharedData); + addBlockingCache(context.vertx(), PROTOCOL_DISPATCHER_CACHE, () -> ProtocolDispatcherCache.init(context), + context::addSharedData); // addBlockingCache(context, CACHE_DATA_TYPE, // () -> Collections.unmodifiableSet(DataType.available().collect(Collectors.toSet()))); return this; } - private void addBlockingCache(@NonNull EntityHandler context, @NonNull String cacheKey, - @NonNull Supplier blockingCacheProvider) { - context.vertx() - .executeBlocking(future -> future.complete(blockingCacheProvider.get()), - result -> context.addSharedData(cacheKey, result.result())); - } - } diff --git a/edge/module/installer/build.gradle b/edge/module/installer/build.gradle index c05b3cb50..fcc9997d9 100644 --- a/edge/module/installer/build.gradle +++ b/edge/module/installer/build.gradle @@ -3,7 +3,5 @@ ext { } dependencies { - compile project(':core:micro') - compile project(':core:installer') - compile project(':eventbus:edge:installer') + compile project(':edge:installer:service') } 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..7572ffad9 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 @@ -5,11 +5,10 @@ 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.rule.RuleRepository; +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; import lombok.NonNull; @@ -21,15 +20,13 @@ protected Class entityHandlerClass() { } @Override - protected Supplier getModuleRuleProvider() { - return new ServiceInstallerRuleProvider(); + protected @NonNull AppDeployerDefinition appDeployerDefinition() { + return AppDeployerDefinition.create("app"); } @Override - protected @NonNull AppDeployer appDeployer() { - return AppDeployer.create(InstallerEventModel.SERVICE_DEPLOYMENT, - InstallerEventModel.SERVICE_DEPLOYMENT_TRACKER, - InstallerEventModel.SERVICE_DEPLOYMENT_FINISHER); + protected @NonNull RuleRepository ruleRepository() { + return RuleRepository.createJVMRule("com.nubeiot.edge.connector", "com.nubeiot.edge.rule"); } @Override diff --git a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProvider.java b/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProvider.java deleted file mode 100644 index 76aa916f5..000000000 --- a/edge/module/installer/src/main/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProvider.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.nubeiot.edge.module.installer; - -import java.util.Arrays; -import java.util.function.Supplier; - -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.loader.ModuleTypeRule; - -final class ServiceInstallerRuleProvider implements Supplier { - - @Override - public ModuleTypeRule get() { - return new ModuleTypeRule().registerRule(ModuleType.JAVA, - Arrays.asList("com.nubeiot.edge.connector", "com.nubeiot.edge.rule")); - } - -} 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/edge/module/installer/src/test/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProviderTest.java b/edge/module/installer/src/test/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProviderTest.java deleted file mode 100644 index 287f17c43..000000000 --- a/edge/module/installer/src/test/java/com/nubeiot/edge/module/installer/ServiceInstallerRuleProviderTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.nubeiot.edge.module.installer; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - -import com.nubeiot.edge.installer.loader.ModuleType; -import com.nubeiot.edge.installer.loader.ModuleTypeRule; - -public class ServiceInstallerRuleProviderTest { - - private ModuleTypeRule rule; - - @Before - public void setup() { - this.rule = new ServiceInstallerRuleProvider().get(); - } - - @Test - public void test_ModuleTypeJAVA_success() { - ModuleTypeRule rule = new ServiceInstallerRuleProvider().get(); - assertTrue(rule.getRule(ModuleType.JAVA).test("com.nubeiot.edge.connector.xyz")); - assertTrue(rule.getSearchPattern(ModuleType.JAVA) - .containsAll(Arrays.asList("com.nubeiot.edge.connector", "com.nubeiot.edge.rule"))); - } - - @Test - public void test_ModuleTypeJAVA_failed() { - assertFalse(rule.getRule(ModuleType.JAVA).test("com.nubeiot.edge.ccc.xyz")); - } - - @Test - public void test_ModuleTypeJAVAScript() { - assertFalse(rule.getRule(ModuleType.JAVASCRIPT).test("olala")); - } - -} diff --git a/eventbus/edge/installer/src/main/java/com/nubeiot/eventbus/edge/installer/InstallerEventModel.java b/eventbus/edge/installer/src/main/java/com/nubeiot/eventbus/edge/installer/InstallerEventModel.java deleted file mode 100644 index dd1931a2f..000000000 --- a/eventbus/edge/installer/src/main/java/com/nubeiot/eventbus/edge/installer/InstallerEventModel.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.nubeiot.eventbus.edge.installer; - -import com.nubeiot.core.event.EventAction; -import com.nubeiot.core.event.EventModel; -import com.nubeiot.core.event.EventPattern; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class InstallerEventModel { - - public static final EventModel SERVICE_DEPLOYMENT = EventModel.builder().address(deployAddr("app")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .addEvents(EventAction.INIT, EventAction.CREATE, - EventAction.UPDATE, EventAction.PATCH, - EventAction.REMOVE) - .build(); - public static final EventModel SERVICE_DEPLOYMENT_TRACKER = EventModel.builder() - .address(trackerAddr("app")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .event(EventAction.MONITOR) - .build(); - public static final EventModel SERVICE_DEPLOYMENT_FINISHER = EventModel.builder() - .address(finisherAddr("app")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .event(EventAction.NOTIFY) - .build(); - - public static final EventModel BIOS_DEPLOYMENT = EventModel.builder().address(deployAddr("bios")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .addEvents(EventAction.INIT, EventAction.CREATE, - EventAction.UPDATE, EventAction.PATCH, - EventAction.REMOVE) - .build(); - public static final EventModel BIOS_DEPLOYMENT_TRACKER = EventModel.builder() - .address(trackerAddr("bios")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .event(EventAction.MONITOR) - .build(); - public static final EventModel BIOS_DEPLOYMENT_FINISHER = EventModel.builder() - .address(finisherAddr("bios")) - .pattern(EventPattern.POINT_2_POINT) - .local(true) - .event(EventAction.NOTIFY) - .build(); - - private static String deployAddr(String app) { - return InstallerEventModel.class.getPackage().getName() + "." + app + ".deployment"; - } - - private static String trackerAddr(String app) { - return InstallerEventModel.class.getPackage().getName() + "." + app + ".deployment.tracker"; - } - - private static String finisherAddr(String app) { - return InstallerEventModel.class.getPackage().getName() + "." + app + ".deployment.finisher"; - } - -} diff --git a/settings.gradle b/settings.gradle index 39b8762e2..c95876aac 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,10 +14,10 @@ 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' -include ':core:installer' include ':core:iotdata' include ':dashboard:server' @@ -29,7 +29,12 @@ include ':dashboard:connector:zeppelin' include ':dashboard:connector:postgresql' include ':dashboard:connector:sample:kafka' + include ':edge:bios' +include ':edge:installer' +include ':edge:installer:model' +include ':edge:installer:rule' +include ':edge:installer:service' include ':edge:module:installer' include ':edge:module:gateway' include ':edge:module:monitor'