From 43e680864cb4acc931a1b34a2df80cd06dbea37b Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 21 Sep 2023 18:18:08 +0400 Subject: [PATCH 1/5] Added auto book feature --- cradle-admin-tool-http/README.md | 22 ++++- .../th2/cradle/adm/http/Application.java | 2 + .../adm/http/AutoBookConfiguration.java | 51 +++++++++++ .../th2/cradle/adm/http/AutoBookUtils.java | 91 +++++++++++++++++++ .../adm/http/AutoPageConfiguration.java | 4 +- .../th2/cradle/adm/http/Configuration.java | 11 ++- .../th2/cradle/adm/http/PageManager.java | 10 +- gradle.properties | 2 +- 8 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java create mode 100644 cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java diff --git a/cradle-admin-tool-http/README.md b/cradle-admin-tool-http/README.md index 7cd2a60..1bd1623 100644 --- a/cradle-admin-tool-http/README.md +++ b/cradle-admin-tool-http/README.md @@ -1,4 +1,4 @@ -# cradle-admin-tool-http (1.7.2) +# cradle-admin-tool-http (1.8.0) Service which allows user to manage books/pages via RestAPI requests. - The first page in a book can be created only if start time is more than current time. - After the first page all new pages must have start time more than current time + `bookRefreshIntervalMillis` * 2 @@ -12,6 +12,10 @@ Service which allows user to manage books/pages via RestAPI requests. - **ip** - host where http cradle admin instance will be instanciated. Default value: `0.0.0.0` - **port** - port on which http server will listen user requests. Default value: `8080` - **page-recheck-interval** - interval in seconds which `PageManager` service checks if new page is required to create or not based on duration values presented in `auto-pages`. Default value: 60 seconds +- **auto-books** - defines rule for automatic books creation. If empty no books will be created automatically. Default value: `empty_map`. + - **book-creation-time** - book creation time. Default value is current time. + - **book-full-name** - book full name. Default value is book name + - **book-description** - book description. Default value is `auto-book` - **auto-pages** - defines rule for automatic pages creation for multiple books. If empty no pages will be created automatically. Default value: `empty_map`. - **page-duration** - defines duration of the page for the book. Value uses the Java Duration format. You can read more about it [here](https://docs.oracle.com/javase/8/docsT/api/java/time/Duration.html#parse-java.lang.CharSequence-). - **page-start-time** - baseline date and time for every new page created by `PageManager` for this book. @@ -29,6 +33,17 @@ spec: custom-config: ip: 198.168.0.2 port: 8080 + auto-book: + book1: + book-creation-time: 2023-03-27T12:00:00 + book-full-name: book1-full-name + book-description: book1-description + book2: + book-creation-time: 2023-03-27T12:00:00 + book-full-name: book1-full-name + book3: + book-creation-time: 2023-03-27T12:00:00 + book4: auto-pages: book1: page-duration: PT60S @@ -44,6 +59,11 @@ spec: ## Release notes +### 1.8.0 + ++ Feature: + + Added auto-book functionality + ### 1.7.2 + Bug fix: diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java index 520bdff..26734e1 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java @@ -51,6 +51,8 @@ public static void main(String[] args) { httpServer.run(); resources.add(httpServer); + AutoBookUtils.createBooks(storage, config.getAutoBooks()); + resources.add( new PageManager( storage, diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java new file mode 100644 index 0000000..3d1c2c3 --- /dev/null +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Exactpro (Exactpro Systems Limited) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.exactpro.th2.cradle.adm.http; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.Instant; + +@SuppressWarnings("FieldMayBeFinal") +public class AutoBookConfiguration { + @JsonProperty("book-full-name") + private String bookFullName = null; + @JsonProperty("book-description") + private String bookDescription = null; + @JsonProperty("book-creation-time") + private Instant bookCreationTime = null; + + public String getBookFullName() { + return bookFullName; + } + + public String getBookDescription() { + return bookDescription; + } + + public Instant getBookCreationTime() { + return bookCreationTime; + } + + @Override + public String toString() { + return "AutoBookConfiguration{" + + "bookFullName='" + bookFullName + '\'' + + ", bookDescription='" + bookDescription + '\'' + + ", bookCreationTime=" + bookCreationTime + + '}'; + } +} diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java new file mode 100644 index 0000000..d2b3d2b --- /dev/null +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java @@ -0,0 +1,91 @@ +/* + * Copyright 2023 Exactpro (Exactpro Systems Limited) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.exactpro.th2.cradle.adm.http; + +import com.exactpro.cradle.BookId; +import com.exactpro.cradle.BookInfo; +import com.exactpro.cradle.BookToAdd; +import com.exactpro.cradle.CradleStorage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.Objects.requireNonNull; +import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.apache.commons.lang3.StringUtils.lowerCase; +import static org.apache.commons.lang3.StringUtils.trim; + +public class AutoBookUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(AutoBookUtils.class); + public static final String AUTO_BOOK_DESCRIPTION = "auto-book"; + + public static void createBooks(@NotNull CradleStorage storage, @Nullable Map autoBooks) { + requireNonNull(storage, "Cradle storage can't be null"); + + if (autoBooks == null || autoBooks.isEmpty()) { + LOGGER.info("Auto book configuration is empty"); + return; + } + + Set existedBooks = storage.getBooks().stream() + .map(BookInfo::getId) + .map(BookId::getName) + .collect(Collectors.toSet()); + + autoBooks.forEach((bookName, config) -> { + try { + bookName = lowerCase(trim(bookName)); + if (bookName == null || bookName.isEmpty()) { + LOGGER.warn("book with null or empty name can't be created"); + } + + if (existedBooks.contains(bookName)) { + return; + } + + BookToAdd bookToAdd; + if (config == null) { + bookToAdd = new BookToAdd(bookName); + bookToAdd.setFullName(bookName); + bookToAdd.setDesc(AUTO_BOOK_DESCRIPTION); + } else { + bookToAdd = new BookToAdd( + bookName, + config.getBookCreationTime() != null ? config.getBookCreationTime() : Instant.now() + ); + bookToAdd.setFullName(trim(defaultIfBlank(config.getBookFullName(), bookName))); + bookToAdd.setDesc(trim(defaultIfBlank(config.getBookDescription(), AUTO_BOOK_DESCRIPTION))); + } + + storage.addBook(bookToAdd); + + LOGGER.info("Created '{}' book, time: {}, full name: {}, description: {}", + bookName, + bookToAdd.getCreated(), + bookToAdd.getFullName(), + bookToAdd.getDesc()); + } catch (Exception e) { + throw new RuntimeException("Book with name '" + bookName + "' and config " + config + " can't be created", e); + } + }); + } +} diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java index 9a7555b..4289dc3 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/* * Copyright 2023 Exactpro (Exactpro Systems Limited) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,7 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - ******************************************************************************/ + */ package com.exactpro.th2.cradle.adm.http; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java index d909d5a..bd7e215 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java @@ -17,6 +17,8 @@ package com.exactpro.th2.cradle.adm.http; import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Collections; import java.util.Map; @SuppressWarnings("FieldMayBeFinal") @@ -35,8 +37,11 @@ public class Configuration { @JsonProperty("page-recheck-interval") private int pageRecheckInterval = DEFAULT_PAGE_RECHECK_INTERVAL_SEC; + @JsonProperty("auto-books") + private Map autoBooks = Collections.emptyMap(); + @JsonProperty("auto-pages") - private Map autoPages; + private Map autoPages = Collections.emptyMap(); public String getIp() { return ip; @@ -46,6 +51,10 @@ public int getPort() { return port; } + public Map getAutoBooks() { + return autoBooks; + } + public Map getAutoPages() { return autoPages; } diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java index 900f387..3c38a80 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; public class PageManager implements AutoCloseable, Runnable{ - private static final Logger logger = LoggerFactory.getLogger(Application.class); + private static final Logger LOGGER = LoggerFactory.getLogger(PageManager.class); private static final String AUTO_PAGE_COMMENT = "auto-page"; private final CradleStorage storage; @@ -49,7 +49,7 @@ public PageManager( long pageActionRejectionThreshold ) throws CradleStorageException { if (autoPages == null || autoPages.isEmpty()) { - logger.info("auto-page configuration is not provided, pages will not be generated automatically"); + LOGGER.info("auto-page configuration is not provided, pages will not be generated automatically"); this.storage = null; this.pageActionRejectionThreshold = 0; this.executorService = null; @@ -65,7 +65,7 @@ public PageManager( books.put(bookName, new AutoPageInfo(autoPages.get(bookName), storage.refreshBook(bookName))); } - logger.info("Managing pages for books {} every {} sec", books.keySet().toArray(), pageRecheckInterval); + LOGGER.info("Managing pages for books {} every {} sec", books.keySet().toArray(), pageRecheckInterval); executorService = Executors.newScheduledThreadPool(1); executorService.scheduleAtFixedRate(this, 0, pageRecheckInterval, TimeUnit.SECONDS); } @@ -106,7 +106,7 @@ public void close() throws Exception { executorService.shutdown(); if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) { List tasks = executorService.shutdownNow(); - logger.warn("Executor can't stop during 5 seconds, " + tasks + " tasks that never commenced execution"); + LOGGER.warn("Executor can't stop during 5 seconds, " + tasks + " tasks that never commenced execution"); } } } @@ -117,7 +117,7 @@ public void run() { try { autoPageInfo.setBookInfo(checkBook(autoPageInfo.getBookInfo(), autoPageInfo.getAutoPageConfiguration())); } catch (Exception e) { - logger.error("Exception processing book {}", bookName, e); + LOGGER.error("Exception processing book {}", bookName, e); } }); } diff --git a/gradle.properties b/gradle.properties index 6e46a89..0863871 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 1.7.2 +release_version = 1.8.0 From e34f9985dea44bc9358ce8405ec4cd199dc2b6e9 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Mon, 25 Sep 2023 15:54:07 +0400 Subject: [PATCH 2/5] corrected after review --- cradle-admin-tool-http/README.md | 20 +--- .../th2/cradle/adm/http/Application.java | 3 +- .../adm/http/AutoBookConfiguration.java | 51 --------- .../th2/cradle/adm/http/AutoBookUtils.java | 91 --------------- .../adm/http/AutoPageConfiguration.java | 9 ++ .../th2/cradle/adm/http/Configuration.java | 8 +- .../th2/cradle/adm/http/PageManager.java | 101 ++++++++++++++--- .../th2/cradle/adm/http/PageManagerTest.java | 104 ++++++++++++++++-- 8 files changed, 196 insertions(+), 191 deletions(-) delete mode 100644 cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java delete mode 100644 cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java diff --git a/cradle-admin-tool-http/README.md b/cradle-admin-tool-http/README.md index 1bd1623..d7b6753 100644 --- a/cradle-admin-tool-http/README.md +++ b/cradle-admin-tool-http/README.md @@ -12,11 +12,9 @@ Service which allows user to manage books/pages via RestAPI requests. - **ip** - host where http cradle admin instance will be instanciated. Default value: `0.0.0.0` - **port** - port on which http server will listen user requests. Default value: `8080` - **page-recheck-interval** - interval in seconds which `PageManager` service checks if new page is required to create or not based on duration values presented in `auto-pages`. Default value: 60 seconds -- **auto-books** - defines rule for automatic books creation. If empty no books will be created automatically. Default value: `empty_map`. - - **book-creation-time** - book creation time. Default value is current time. - - **book-full-name** - book full name. Default value is book name - - **book-description** - book description. Default value is `auto-book` -- **auto-pages** - defines rule for automatic pages creation for multiple books. If empty no pages will be created automatically. Default value: `empty_map`. +- **auto-book** - if `true` than cradle-admin-tool creates books with first page for each value from `auto-pages` option when target book doesn't exist in cradle. + Creation book time is calculate by the `current time - 1 day` formula to cover events and messages published a bit earlier than cradle-admin-tool started. Please note you can create your own book via REST API later. +- **auto-pages** - defines rule for automatic pages creation for multiple books. If empty no pages will be created automatically. Default value: `false`. - **page-duration** - defines duration of the page for the book. Value uses the Java Duration format. You can read more about it [here](https://docs.oracle.com/javase/8/docsT/api/java/time/Duration.html#parse-java.lang.CharSequence-). - **page-start-time** - baseline date and time for every new page created by `PageManager` for this book. @@ -33,17 +31,7 @@ spec: custom-config: ip: 198.168.0.2 port: 8080 - auto-book: - book1: - book-creation-time: 2023-03-27T12:00:00 - book-full-name: book1-full-name - book-description: book1-description - book2: - book-creation-time: 2023-03-27T12:00:00 - book-full-name: book1-full-name - book3: - book-creation-time: 2023-03-27T12:00:00 - book4: + auto-book: true auto-pages: book1: page-duration: PT60S diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java index 26734e1..d30b019 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Application.java @@ -51,11 +51,10 @@ public static void main(String[] args) { httpServer.run(); resources.add(httpServer); - AutoBookUtils.createBooks(storage, config.getAutoBooks()); - resources.add( new PageManager( storage, + config.isAutoBook(), config.getAutoPages(), config.getPageRecheckInterval(), settings.calculatePageActionRejectionThreshold() * 2 diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java deleted file mode 100644 index 3d1c2c3..0000000 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2023 Exactpro (Exactpro Systems Limited) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.exactpro.th2.cradle.adm.http; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.time.Instant; - -@SuppressWarnings("FieldMayBeFinal") -public class AutoBookConfiguration { - @JsonProperty("book-full-name") - private String bookFullName = null; - @JsonProperty("book-description") - private String bookDescription = null; - @JsonProperty("book-creation-time") - private Instant bookCreationTime = null; - - public String getBookFullName() { - return bookFullName; - } - - public String getBookDescription() { - return bookDescription; - } - - public Instant getBookCreationTime() { - return bookCreationTime; - } - - @Override - public String toString() { - return "AutoBookConfiguration{" + - "bookFullName='" + bookFullName + '\'' + - ", bookDescription='" + bookDescription + '\'' + - ", bookCreationTime=" + bookCreationTime + - '}'; - } -} diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java deleted file mode 100644 index d2b3d2b..0000000 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoBookUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2023 Exactpro (Exactpro Systems Limited) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.exactpro.th2.cradle.adm.http; - -import com.exactpro.cradle.BookId; -import com.exactpro.cradle.BookInfo; -import com.exactpro.cradle.BookToAdd; -import com.exactpro.cradle.CradleStorage; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.Instant; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.util.Objects.requireNonNull; -import static org.apache.commons.lang3.StringUtils.defaultIfBlank; -import static org.apache.commons.lang3.StringUtils.lowerCase; -import static org.apache.commons.lang3.StringUtils.trim; - -public class AutoBookUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(AutoBookUtils.class); - public static final String AUTO_BOOK_DESCRIPTION = "auto-book"; - - public static void createBooks(@NotNull CradleStorage storage, @Nullable Map autoBooks) { - requireNonNull(storage, "Cradle storage can't be null"); - - if (autoBooks == null || autoBooks.isEmpty()) { - LOGGER.info("Auto book configuration is empty"); - return; - } - - Set existedBooks = storage.getBooks().stream() - .map(BookInfo::getId) - .map(BookId::getName) - .collect(Collectors.toSet()); - - autoBooks.forEach((bookName, config) -> { - try { - bookName = lowerCase(trim(bookName)); - if (bookName == null || bookName.isEmpty()) { - LOGGER.warn("book with null or empty name can't be created"); - } - - if (existedBooks.contains(bookName)) { - return; - } - - BookToAdd bookToAdd; - if (config == null) { - bookToAdd = new BookToAdd(bookName); - bookToAdd.setFullName(bookName); - bookToAdd.setDesc(AUTO_BOOK_DESCRIPTION); - } else { - bookToAdd = new BookToAdd( - bookName, - config.getBookCreationTime() != null ? config.getBookCreationTime() : Instant.now() - ); - bookToAdd.setFullName(trim(defaultIfBlank(config.getBookFullName(), bookName))); - bookToAdd.setDesc(trim(defaultIfBlank(config.getBookDescription(), AUTO_BOOK_DESCRIPTION))); - } - - storage.addBook(bookToAdd); - - LOGGER.info("Created '{}' book, time: {}, full name: {}, description: {}", - bookName, - bookToAdd.getCreated(), - bookToAdd.getFullName(), - bookToAdd.getDesc()); - } catch (Exception e) { - throw new RuntimeException("Book with name '" + bookName + "' and config " + config + " can't be created", e); - } - }); - } -} diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java index 4289dc3..e345750 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/AutoPageConfiguration.java @@ -16,6 +16,7 @@ package com.exactpro.th2.cradle.adm.http; import com.fasterxml.jackson.annotation.JsonProperty; + import java.time.Duration; import java.time.Instant; @@ -34,4 +35,12 @@ public Duration getPageDuration() { public Instant getPageStartTime() { return pageStartTime; } + + public void setPageDuration(Duration pageDuration) { + this.pageDuration = pageDuration; + } + + public void setPageStartTime(Instant pageStartTime) { + this.pageStartTime = pageStartTime; + } } diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java index bd7e215..ae3b111 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java @@ -37,8 +37,8 @@ public class Configuration { @JsonProperty("page-recheck-interval") private int pageRecheckInterval = DEFAULT_PAGE_RECHECK_INTERVAL_SEC; - @JsonProperty("auto-books") - private Map autoBooks = Collections.emptyMap(); + @JsonProperty("auto-book") + private boolean autoBook = false; @JsonProperty("auto-pages") private Map autoPages = Collections.emptyMap(); @@ -51,8 +51,8 @@ public int getPort() { return port; } - public Map getAutoBooks() { - return autoBooks; + public boolean isAutoBook() { + return autoBook; } public Map getAutoPages() { diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java index 3c38a80..923b1d8 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java @@ -17,25 +17,34 @@ package com.exactpro.th2.cradle.adm.http; import com.exactpro.cradle.BookInfo; +import com.exactpro.cradle.BookToAdd; import com.exactpro.cradle.CradleStorage; import com.exactpro.cradle.PageInfo; import com.exactpro.cradle.utils.CradleStorageException; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; import java.time.Duration; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.apache.commons.lang3.StringUtils.lowerCase; +import static org.apache.commons.lang3.StringUtils.trim; public class PageManager implements AutoCloseable, Runnable{ private static final Logger LOGGER = LoggerFactory.getLogger(PageManager.class); - private static final String AUTO_PAGE_COMMENT = "auto-page"; + static final String AUTO_PAGE_COMMENT = "auto-page"; + static final String AUTO_BOOK_DESCRIPTION = "auto-book"; private final CradleStorage storage; private final long pageActionRejectionThreshold; @@ -44,10 +53,11 @@ public class PageManager implements AutoCloseable, Runnable{ public PageManager( CradleStorage storage, + boolean autoBooks, Map autoPages, int pageRecheckInterval, long pageActionRejectionThreshold - ) throws CradleStorageException { + ) { if (autoPages == null || autoPages.isEmpty()) { LOGGER.info("auto-page configuration is not provided, pages will not be generated automatically"); this.storage = null; @@ -57,43 +67,64 @@ public PageManager( return; } - this.storage = storage; - this.pageActionRejectionThreshold = pageActionRejectionThreshold; + Map normalisedBookName = autoPages.keySet().stream() + .collect(Collectors.toMap( + PageManager::normaliseBookName, + Function.identity() + )); - books = new HashMap<>(); - for (String bookName : autoPages.keySet()) { - books.put(bookName, new AutoPageInfo(autoPages.get(bookName), storage.refreshBook(bookName))); + if (normalisedBookName.size() != autoPages.size()) { + throw new IllegalArgumentException("Some of books have the same name after normalization" + + ", origin: " + autoPages.keySet() + + ", normalized: " + normalisedBookName.keySet()); } + books = normalisedBookName.entrySet().stream() + .collect(Collectors.toUnmodifiableMap( + Map.Entry::getKey, + entry -> new AutoPageInfo(autoPages.get(entry.getValue()), getOrCreateBook(storage, entry.getKey(), autoBooks)) + )); + + this.storage = storage; + this.pageActionRejectionThreshold = pageActionRejectionThreshold; + LOGGER.info("Managing pages for books {} every {} sec", books.keySet().toArray(), pageRecheckInterval); executorService = Executors.newScheduledThreadPool(1); executorService.scheduleAtFixedRate(this, 0, pageRecheckInterval, TimeUnit.SECONDS); } + @NotNull + private static String normaliseBookName(String origin) { + String bookName = lowerCase(trim(origin)); + if (bookName == null || bookName.isEmpty()) { + throw new IllegalArgumentException("One of book is null or empty"); + } + return bookName; + } + private BookInfo checkBook(BookInfo book, AutoPageConfiguration autoPageConfiguration) throws Exception { Instant pageStartBase = autoPageConfiguration.getPageStartTime(); Duration pageDuration = autoPageConfiguration.getPageDuration(); Instant nowPlusThreshold = Instant.now().plusMillis(pageActionRejectionThreshold); - long nowMillis = nowPlusThreshold.toEpochMilli(); PageInfo pageInfo = book.getLastPage(); if (pageInfo == null) { - return storage.addPage(book.getId(), "auto-page-" + nowMillis, nowPlusThreshold, AUTO_PAGE_COMMENT); + return createAutoPage(storage, book, nowPlusThreshold); } Instant lastPageStart = pageInfo.getStarted(); if (lastPageStart.isBefore(nowPlusThreshold)) { int comparison = nowPlusThreshold.compareTo(pageStartBase); if (comparison < 0) { - return storage.addPage(book.getId(), "auto-page-" + nowMillis, pageStartBase, AUTO_PAGE_COMMENT); + return createAutoPage(storage, book, pageStartBase); } else if (comparison > 0) { Duration diff = Duration.between(pageStartBase, nowPlusThreshold); Instant nextMark = pageStartBase.plus(pageDuration.multipliedBy(diff.dividedBy(pageDuration) + 1)); - return storage.addPage(book.getId(), "auto-page-" + nowMillis, nextMark, AUTO_PAGE_COMMENT); + return createAutoPage(storage, book, nextMark); } else { - return storage.addPage(book.getId(), "auto-page-" + nowMillis, pageStartBase.plus(pageDuration), AUTO_PAGE_COMMENT); + return createAutoPage(storage, book, pageStartBase.plus(pageDuration)); } } @@ -121,4 +152,44 @@ public void run() { } }); } + + private static BookInfo getOrCreateBook(@NotNull CradleStorage storage, String bookName, boolean autoBook) { + try { + BookInfo storageBookInfo = storage.refreshBook(bookName); + + if (storageBookInfo != null) { + return storageBookInfo; + } + + if (!autoBook) { + throw new IllegalStateException("Storage doesn't contain the '" + bookName + "' book, auto book: false"); + } + + BookToAdd bookToAdd = new BookToAdd( + bookName, + Instant.now().minus(1, ChronoUnit.DAYS) + ); + bookToAdd.setFullName(bookName); + bookToAdd.setDesc(AUTO_BOOK_DESCRIPTION); + + BookInfo bookInfo = storage.addBook(bookToAdd); + + LOGGER.info("Created '{}' book, time: {}, full name: {}, description: {}", + bookName, + bookToAdd.getCreated(), + bookToAdd.getFullName(), + bookToAdd.getDesc()); + + createAutoPage(storage, bookInfo, bookInfo.getCreated()); + LOGGER.info("Added first page, book: {}, time: {}", bookInfo.getId().getName(), bookInfo.getCreated()); + return bookInfo; + } catch (Exception e) { + throw new RuntimeException("Book with name '" + bookName + "' can't be created", e); + } + } + + private static BookInfo createAutoPage(CradleStorage storage, BookInfo book, Instant nowPlusThreshold) throws CradleStorageException, IOException { + long nowMillis = nowPlusThreshold.toEpochMilli(); + return storage.addPage(book.getId(), "auto-page-" + nowMillis, nowPlusThreshold, AUTO_PAGE_COMMENT); + } } diff --git a/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java b/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java index 5d776cb..fce1bcf 100644 --- a/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java +++ b/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java @@ -19,6 +19,8 @@ import com.exactpro.cradle.BookInfo; import com.exactpro.cradle.CradleStorage; import com.exactpro.cradle.PageInfo; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -27,7 +29,11 @@ import java.time.temporal.ChronoUnit; import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; @@ -47,10 +53,10 @@ public void autoPage(boolean baseTimeBefore) throws Exception { Duration duration = Duration.of(100, ChronoUnit.SECONDS); long threshold = duration.dividedBy(2).toMillis(); - BookInfo longTimeBefore = createBookInfo(now.minus(duration.multipliedBy(2)), "a long time before"); - BookInfo before = createBookInfo(now.minus(duration), "before"); - BookInfo equal = createBookInfo(now, "equal"); - BookInfo after = createBookInfo(now.plus(duration), "after"); + BookInfo longTimeBefore = createBookInfoWithPage(now.minus(duration.multipliedBy(2)), "a long time before"); + BookInfo before = createBookInfoWithPage(now.minus(duration), "before"); + BookInfo equal = createBookInfoWithPage(now, "equal"); + BookInfo after = createBookInfoWithPage(now.plus(duration), "after"); CradleStorage mockStorage = mock(CradleStorage.class); when(mockStorage.refreshBook(same(longTimeBefore.getFullName()))).thenReturn(longTimeBefore); @@ -62,9 +68,9 @@ public void autoPage(boolean baseTimeBefore) throws Exception { when(mockStorage.addPage(same(equal.getId()), any(), any(), any())).thenReturn(equal); when(mockStorage.addPage(same(after.getId()), any(), any(), any())).thenReturn(after); - AutoPageConfiguration autoPageConfig = mock(AutoPageConfiguration.class); - when(autoPageConfig.getPageDuration()).thenReturn(duration); - when(autoPageConfig.getPageStartTime()).thenReturn(baseTimeBefore ? now.minus(duration) : now.plus(duration)); + AutoPageConfiguration autoPageConfig = new AutoPageConfiguration(); + autoPageConfig.setPageDuration(duration); + autoPageConfig.setPageStartTime(baseTimeBefore ? now.minus(duration) : now.plus(duration)); Map mapping = Map.of( @@ -73,7 +79,7 @@ public void autoPage(boolean baseTimeBefore) throws Exception { equal.getId().getName(), autoPageConfig, after.getId().getName(), autoPageConfig ); - try (PageManager ignored = new PageManager(mockStorage, mapping, 60*60*12, threshold)) { + try (PageManager ignored = new PageManager(mockStorage, false, mapping, 60*60*12, threshold)) { verify(mockStorage).refreshBook(longTimeBefore.getId().getName()); verify(mockStorage).refreshBook(before.getId().getName()); verify(mockStorage).refreshBook(equal.getId().getName()); @@ -81,9 +87,9 @@ public void autoPage(boolean baseTimeBefore) throws Exception { verify(mockStorage, timeout(1000)) .addPage(same(longTimeBefore.getId()), any(), eq(now.plus(duration)), any()); - verify(mockStorage) + verify(mockStorage, timeout(1000)) .addPage(same(before.getId()), any(), eq(now.plus(duration)), any()); - verify(mockStorage) + verify(mockStorage, timeout(1000)) .addPage(same(equal.getId()), any(), eq(now.plus(duration)), any()); verify(mockStorage, never()) .addPage(same(after.getId()), any(), any(), any()); @@ -92,13 +98,87 @@ public void autoPage(boolean baseTimeBefore) throws Exception { } } - private BookInfo createBookInfo(Instant lastStarted, String fullName) { + @Test + public void emptyStorageAndAutoBookFalse() { + Instant now = Instant.now(); + + Duration duration = Duration.of(100, ChronoUnit.SECONDS); + long threshold = duration.dividedBy(2).toMillis(); + + CradleStorage mockStorage = mock(CradleStorage.class); + + AutoPageConfiguration autoPageConfig = new AutoPageConfiguration(); + autoPageConfig.setPageDuration(duration); + autoPageConfig.setPageStartTime(now.plus(duration)); + + String book = "test-new-book"; + Map mapping = Map.of( + book, autoPageConfig + ); + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> new PageManager(mockStorage, false, mapping, 60*60*12, threshold).close()); + assertEquals("Book with name '" + book + "' can't be created", runtimeException.getMessage()); + } + + @Test + public void createAutoBook() throws Exception { + Instant now = Instant.now(); + + Duration duration = Duration.of(100, ChronoUnit.SECONDS); + long threshold = duration.dividedBy(2).toMillis(); + + BookInfo existedBook = createBookInfoWithPage(now.minus(duration), "test-existed-book"); + BookInfo newBook = createBookInfo("test-new-book", now.minus(1, ChronoUnit.DAYS)); + + CradleStorage mockStorage = mock(CradleStorage.class); + when(mockStorage.refreshBook(same(existedBook.getId().getName()))).thenReturn(existedBook); + when(mockStorage.addBook(argThat((bookToAdd) -> newBook.getId().getName().equals(bookToAdd.getName()) + && Instant.now().minus(1, ChronoUnit.DAYS).isAfter(bookToAdd.getCreated()) + ))).thenReturn(newBook); + when(mockStorage.addPage(same(existedBook.getId()), any(), any(), any())).thenReturn(existedBook); + when(mockStorage.addPage(same(newBook.getId()), any(), any(), any())).thenReturn(newBook); + + AutoPageConfiguration autoPageConfig = new AutoPageConfiguration(); + autoPageConfig.setPageDuration(duration); + autoPageConfig.setPageStartTime(now.plus(duration)); + + Map mapping = Map.of( + existedBook.getId().getName(), autoPageConfig, + newBook.getId().getName(), autoPageConfig + ); + try (PageManager ignored = new PageManager(mockStorage, true, mapping, 60*60*12, threshold)) { + verify(mockStorage).refreshBook(existedBook.getId().getName()); + verify(mockStorage).refreshBook(newBook.getId().getName()); + + verify(mockStorage).addBook(argThat((bookToAdd) -> newBook.getId().getName().equals(bookToAdd.getName()))); + + verify(mockStorage) + .addPage(same(newBook.getId()), anyString(), eq(now.minus(1, ChronoUnit.DAYS)), anyString()); + + verify(mockStorage, timeout(1000)) + .addPage(eq(existedBook.getId()), any(), eq(now.plus(duration)), any()); + verify(mockStorage, timeout(1000)) + .addPage(eq(newBook.getId()), any(), argThat((pageStart) -> + Instant.now().plus(duration).isAfter(pageStart) && Instant.now().isBefore(pageStart) + ), any()); + + verifyNoMoreInteractions(mockStorage); + } + } + + private BookInfo createBookInfoWithPage(Instant lastStarted, String fullName) { PageInfo pageInfoMock = mock(PageInfo.class); when(pageInfoMock.getStarted()).thenReturn(lastStarted); + BookInfo bookInfoMock = createBookInfo(fullName, lastStarted); + when(bookInfoMock.getLastPage()).thenReturn(pageInfoMock); + return bookInfoMock; + } + + @NotNull + private static BookInfo createBookInfo(String fullName, Instant created) { BookInfo bookInfoMock = mock(BookInfo.class); when(bookInfoMock.getId()).thenReturn(new BookId(fullName)); - when(bookInfoMock.getLastPage()).thenReturn(pageInfoMock); + when(bookInfoMock.getCreated()).thenReturn(created); when(bookInfoMock.getFullName()).thenReturn(fullName); return bookInfoMock; } From 28f715762b2ef6fded4e230253ea50b48916e53c Mon Sep 17 00:00:00 2001 From: Nikita Smirnov <46124551+Nikita-Smirnov-Exactpro@users.noreply.github.com> Date: Tue, 26 Sep 2023 10:20:31 +0400 Subject: [PATCH 3/5] Update cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java Co-authored-by: Oleg Smirnov --- .../main/java/com/exactpro/th2/cradle/adm/http/PageManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java index 923b1d8..0624c65 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java @@ -162,7 +162,7 @@ private static BookInfo getOrCreateBook(@NotNull CradleStorage storage, String b } if (!autoBook) { - throw new IllegalStateException("Storage doesn't contain the '" + bookName + "' book, auto book: false"); + throw new IllegalStateException("Storage doesn't contain the '" + bookName + "' book. Create book manually or enable auto-book functionality in configuration"); } BookToAdd bookToAdd = new BookToAdd( From eac5645e7b8560d5bf83ff81774a373c0c5521f8 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Tue, 26 Sep 2023 19:34:29 +0400 Subject: [PATCH 4/5] corrected after review --- cradle-admin-tool-http/README.md | 5 +++-- .../th2/cradle/adm/http/Configuration.java | 2 +- .../th2/cradle/adm/http/PageManager.java | 11 ++++++++--- .../th2/cradle/adm/http/PageManagerTest.java | 17 ++++++++++++++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/cradle-admin-tool-http/README.md b/cradle-admin-tool-http/README.md index d7b6753..a1b982c 100644 --- a/cradle-admin-tool-http/README.md +++ b/cradle-admin-tool-http/README.md @@ -13,8 +13,9 @@ Service which allows user to manage books/pages via RestAPI requests. - **port** - port on which http server will listen user requests. Default value: `8080` - **page-recheck-interval** - interval in seconds which `PageManager` service checks if new page is required to create or not based on duration values presented in `auto-pages`. Default value: 60 seconds - **auto-book** - if `true` than cradle-admin-tool creates books with first page for each value from `auto-pages` option when target book doesn't exist in cradle. - Creation book time is calculate by the `current time - 1 day` formula to cover events and messages published a bit earlier than cradle-admin-tool started. Please note you can create your own book via REST API later. -- **auto-pages** - defines rule for automatic pages creation for multiple books. If empty no pages will be created automatically. Default value: `false`. + Creation book time is calculate by the `current time - 1 day` formula to cover events and messages published a bit earlier than cradle-admin-tool started. Default value: `true`. + Please note you can create your own book via REST API later. +- **auto-pages** - defines rule for automatic pages creation for multiple books. If empty no pages will be created automatically. - **page-duration** - defines duration of the page for the book. Value uses the Java Duration format. You can read more about it [here](https://docs.oracle.com/javase/8/docsT/api/java/time/Duration.html#parse-java.lang.CharSequence-). - **page-start-time** - baseline date and time for every new page created by `PageManager` for this book. diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java index ae3b111..84cfa64 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/Configuration.java @@ -38,7 +38,7 @@ public class Configuration { private int pageRecheckInterval = DEFAULT_PAGE_RECHECK_INTERVAL_SEC; @JsonProperty("auto-book") - private boolean autoBook = false; + private boolean autoBook = true; @JsonProperty("auto-pages") private Map autoPages = Collections.emptyMap(); diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java index 0624c65..072c3e1 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java @@ -17,6 +17,7 @@ package com.exactpro.th2.cradle.adm.http; import com.exactpro.cradle.BookInfo; +import com.exactpro.cradle.BookListEntry; import com.exactpro.cradle.BookToAdd; import com.exactpro.cradle.CradleStorage; import com.exactpro.cradle.PageInfo; @@ -32,6 +33,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -155,10 +157,13 @@ public void run() { private static BookInfo getOrCreateBook(@NotNull CradleStorage storage, String bookName, boolean autoBook) { try { - BookInfo storageBookInfo = storage.refreshBook(bookName); + BookListEntry bookListEntry = storage.listBooks().stream() + .filter(entry -> Objects.equals(entry.getName(), bookName)) + .findFirst() + .orElse(null); - if (storageBookInfo != null) { - return storageBookInfo; + if (bookListEntry != null) { + return storage.refreshBook(bookName); } if (!autoBook) { diff --git a/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java b/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java index fce1bcf..7db6a2c 100644 --- a/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java +++ b/cradle-admin-tool-http/src/test/java/com/exactpro/th2/cradle/adm/http/PageManagerTest.java @@ -17,6 +17,7 @@ import com.exactpro.cradle.BookId; import com.exactpro.cradle.BookInfo; +import com.exactpro.cradle.BookListEntry; import com.exactpro.cradle.CradleStorage; import com.exactpro.cradle.PageInfo; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,7 @@ import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -39,12 +41,15 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class PageManagerTest { + private static final String SCHEMA_VERSION = "test-schema-version"; + @ParameterizedTest @ValueSource(booleans = { true, false }) public void autoPage(boolean baseTimeBefore) throws Exception { @@ -59,6 +64,13 @@ public void autoPage(boolean baseTimeBefore) throws Exception { BookInfo after = createBookInfoWithPage(now.plus(duration), "after"); CradleStorage mockStorage = mock(CradleStorage.class); + List listEntries = List.of( + new BookListEntry(longTimeBefore.getId().getName(), SCHEMA_VERSION), + new BookListEntry(before.getId().getName(), SCHEMA_VERSION), + new BookListEntry(equal.getId().getName(), SCHEMA_VERSION), + new BookListEntry(after.getId().getName(), SCHEMA_VERSION) + ); + when(mockStorage.listBooks()).thenReturn(listEntries); when(mockStorage.refreshBook(same(longTimeBefore.getFullName()))).thenReturn(longTimeBefore); when(mockStorage.refreshBook(same(before.getId().getName()))).thenReturn(before); when(mockStorage.refreshBook(same(equal.getId().getName()))).thenReturn(equal); @@ -80,6 +92,7 @@ public void autoPage(boolean baseTimeBefore) throws Exception { after.getId().getName(), autoPageConfig ); try (PageManager ignored = new PageManager(mockStorage, false, mapping, 60*60*12, threshold)) { + verify(mockStorage, times(4)).listBooks(); verify(mockStorage).refreshBook(longTimeBefore.getId().getName()); verify(mockStorage).refreshBook(before.getId().getName()); verify(mockStorage).refreshBook(equal.getId().getName()); @@ -130,6 +143,8 @@ public void createAutoBook() throws Exception { BookInfo newBook = createBookInfo("test-new-book", now.minus(1, ChronoUnit.DAYS)); CradleStorage mockStorage = mock(CradleStorage.class); + List listEntries = List.of(new BookListEntry(existedBook.getId().getName(), SCHEMA_VERSION)); + when(mockStorage.listBooks()).thenReturn(listEntries); when(mockStorage.refreshBook(same(existedBook.getId().getName()))).thenReturn(existedBook); when(mockStorage.addBook(argThat((bookToAdd) -> newBook.getId().getName().equals(bookToAdd.getName()) && Instant.now().minus(1, ChronoUnit.DAYS).isAfter(bookToAdd.getCreated()) @@ -146,8 +161,8 @@ public void createAutoBook() throws Exception { newBook.getId().getName(), autoPageConfig ); try (PageManager ignored = new PageManager(mockStorage, true, mapping, 60*60*12, threshold)) { + verify(mockStorage, times(2)).listBooks(); verify(mockStorage).refreshBook(existedBook.getId().getName()); - verify(mockStorage).refreshBook(newBook.getId().getName()); verify(mockStorage).addBook(argThat((bookToAdd) -> newBook.getId().getName().equals(bookToAdd.getName()))); From 90a9a6d3984c76a5c33dc756d7ba48b605bb0f7e Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 28 Sep 2023 10:55:28 +0400 Subject: [PATCH 5/5] corrected after review --- .../com/exactpro/th2/cradle/adm/http/PageManager.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java index 072c3e1..15d028f 100644 --- a/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java +++ b/cradle-admin-tool-http/src/main/java/com/exactpro/th2/cradle/adm/http/PageManager.java @@ -37,7 +37,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.function.Function; import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.lowerCase; @@ -69,10 +68,10 @@ public PageManager( return; } - Map normalisedBookName = autoPages.keySet().stream() + Map normalisedBookName = autoPages.entrySet().stream() .collect(Collectors.toMap( - PageManager::normaliseBookName, - Function.identity() + entry -> normaliseBookName(entry.getKey()), + Map.Entry::getValue )); if (normalisedBookName.size() != autoPages.size()) { @@ -84,7 +83,7 @@ public PageManager( books = normalisedBookName.entrySet().stream() .collect(Collectors.toUnmodifiableMap( Map.Entry::getKey, - entry -> new AutoPageInfo(autoPages.get(entry.getValue()), getOrCreateBook(storage, entry.getKey(), autoBooks)) + entry -> new AutoPageInfo(entry.getValue(), getOrCreateBook(storage, entry.getKey(), autoBooks)) )); this.storage = storage;