diff --git a/.github/workflows/ga-publication.yml b/.github/workflows/ga-publication.yml index fb801c780..8a5260edc 100644 --- a/.github/workflows/ga-publication.yml +++ b/.github/workflows/ga-publication.yml @@ -41,7 +41,7 @@ jobs: --id "CHECKOUT FOR GA PUBLICATION" \ --lcd "$LOCAL_CLONE_DIR" - name: "Cache Maven packages" - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f47532c31..63369add4 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -95,7 +95,7 @@ jobs: java-version: 11 #~ MAVEN CACHE - name: "Cache Maven packages" - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2 @@ -103,13 +103,13 @@ jobs: #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: "${{ env.LOCAL_CLONE_DIR }}/target/" key: ${{ runner.os }}-build-${{ env.BUILD_CACHE_KEY }} #~ SONAR CACHE - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v4 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar @@ -151,7 +151,7 @@ jobs: #~ MAVEN CACHE - name: "Cache Maven packages" id: maven-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-matrix-${{ matrix.scan-type }} @@ -162,7 +162,7 @@ jobs: #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: "${{ env.LOCAL_CLONE_DIR}}/target/" key: ${{ runner.os }}-build-${{ env.BUILD_CACHE_KEY }} @@ -177,6 +177,7 @@ jobs: export ENTANDO_OPT_SONAR_PROJECT_KEY="${{ secrets.ENTANDO_OPT_SONAR_PROJECT_KEY }}" ;; MTX-SCAN-SNYK) + exit 0 export SNYK_TOKEN="${{ secrets.SNYK_TOKEN }}" ;; MTX-MVN-POST-DEPLOYMENT-TESTS) diff --git a/.github/workflows/publication.yml b/.github/workflows/publication.yml index 07d472be6..7834d68e5 100644 --- a/.github/workflows/publication.yml +++ b/.github/workflows/publication.yml @@ -56,7 +56,7 @@ jobs: java-version: 11 #~ MAVEN CACHE - name: "Cache Maven packages" - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2 @@ -64,7 +64,7 @@ jobs: #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: "${{ env.LOCAL_CLONE_DIR }}/target/" key: ${{ runner.os }}-build-${{ env.BUILD_CACHE_KEY }} @@ -131,7 +131,7 @@ jobs: java-version: 11 #~ MAVEN CACHE - name: "Cache Maven packages" - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2 @@ -139,7 +139,7 @@ jobs: #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: "${{ env.LOCAL_CLONE_DIR }}/target/" key: ${{ runner.os }}-build-${{ env.BUILD_CACHE_KEY }} @@ -177,7 +177,7 @@ jobs: java-version: 11 #~ MAVEN CACHE - name: "Cache Maven packages" - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2 @@ -185,7 +185,7 @@ jobs: #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: "${{ env.LOCAL_CLONE_DIR }}/target/" key: ${{ runner.os }}-build-${{ env.BUILD_CACHE_KEY }} diff --git a/pom.xml b/pom.xml index 6e6aa67a9..e3d1c8ce5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,11 +5,11 @@ org.entando entando-core-parent - 6.5.0-ENG-5128-PR-156 + 6.5.0 org.entando.entando entando-admin-console - 6.5.2 + 6.5.3 war Entando Core: Administration Console Entando Administration Console: an agile, modern and user-centric open source Portal platform. @@ -88,6 +88,22 @@ + + maven-jar-plugin + + + tests + package + + jar + + + tests + ${project.build.test-classes} + + + + org.apache.maven.plugins maven-release-plugin @@ -212,7 +228,7 @@ org.entando entando-core-bom - 6.5.0-ENG-5128 + 6.5.1 import pom @@ -222,12 +238,14 @@ org.entando.entando entando-engine + 6.5.5 org.entando.entando entando-engine test-jar test + 6.5.5 org.apache.struts @@ -273,6 +291,10 @@ org.mockito mockito-junit-jupiter + + org.mockito + mockito-inline + javax.servlet javax.servlet-api diff --git a/src/main/java/com/agiletec/apsadmin/admin/BaseAdminAction.java b/src/main/java/com/agiletec/apsadmin/admin/BaseAdminAction.java index 601db291e..fdc4f1659 100644 --- a/src/main/java/com/agiletec/apsadmin/admin/BaseAdminAction.java +++ b/src/main/java/com/agiletec/apsadmin/admin/BaseAdminAction.java @@ -13,15 +13,7 @@ */ package com.agiletec.apsadmin.admin; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.entando.entando.ent.util.EntLogging.EntLogger; -import org.entando.entando.ent.util.EntLogging.EntLogFactory; -import org.springframework.web.context.WebApplicationContext; +import static com.agiletec.apsadmin.admin.reload.ReloadConfigThread.RELOAD_THREAD; import com.agiletec.aps.system.SystemConstants; import com.agiletec.aps.system.common.entity.event.ReloadingEntitiesReferencesEvent; @@ -31,7 +23,18 @@ import com.agiletec.aps.system.services.page.IPage; import com.agiletec.aps.system.services.page.IPageManager; import com.agiletec.aps.util.ApsWebApplicationUtils; +import com.agiletec.apsadmin.admin.reload.ReloadConfigThread; import com.agiletec.apsadmin.system.BaseAction; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.entando.entando.ent.util.EntLogging.EntLogFactory; +import org.entando.entando.ent.util.EntLogging.EntLogger; +import org.springframework.web.context.WebApplicationContext; /** * This base action implements the default actions available for the system @@ -43,6 +46,10 @@ public class BaseAdminAction extends BaseAction { private static final EntLogger logger = EntLogFactory.getSanitizedLogger(BaseAdminAction.class); + public static final String RELOAD_ERROR = "reloadError"; + public static final String IN_PROGRESS = "inProgress"; + public static final String NEW_PARAM_MARKER = "_newParamMarker"; + /** * Reload the system configuration. * @@ -50,16 +57,50 @@ public class BaseAdminAction extends BaseAction { */ public String reloadConfig() { try { - ApsWebApplicationUtils.executeSystemRefresh(this.getRequest()); - logger.info("Reload config started"); - this.setReloadingResult(SUCCESS_RELOADING_RESULT_CODE); - } catch (Throwable t) { - logger.error("error in reloadConfig", t); + if (!ApsWebApplicationUtils.isReloadInProgress()) { + ReloadConfigThread rct = new ReloadConfigThread(this.getRequest()); + logger.info("Starting reload configuration thread"); + rct.start(); + } else { + logger.info("Reload operation already in progress!"); + } + this.setReloadingResult(PROGRESS_RELOADING_RESULT_CODE); + } catch (Exception e) { + logger.error("unexpected error while launching system reload", e); this.setReloadingResult(FAILURE_RELOADING_RESULT_CODE); + return RELOAD_ERROR; + } + return SUCCESS; + } + + public String reloadStatus() { + if (ApsWebApplicationUtils.isReloadInProgress()) { + this.setReloadingResult(PROGRESS_RELOADING_RESULT_CODE); + return IN_PROGRESS; } + updateReloadStatusResult(); return SUCCESS; } + public String reloadStatusJson() { + return SUCCESS; + } + + public boolean isReloadingErrorDetect() { + return ApsWebApplicationUtils.getReloadInfo() + .values() + .stream() + .anyMatch(StringUtils::isNotBlank); + } + + public int getReloadProgress() { + return ApsWebApplicationUtils.getReloadProgress(); + } + + public Map getReloadInfo() { + return new HashMap<>(ApsWebApplicationUtils.getReloadInfo()); + } + /** * Reload the references of all the existing entities. * @@ -87,7 +128,7 @@ public void setReloadingResult(int reloadingResult) { } /** - * Get the system parameters in order to edit them. + * Get the system parameters to edit them. * * @return the result code. */ @@ -144,7 +185,7 @@ protected String getConfigParameter() { * Refresh the map of parameters with values fetched from the request * * @param keepOldParam when true, when a system parameter is not found in - * request, the previous system parameter will be stored + * the request, the previous system parameter will be stored */ protected void updateLocalParams(boolean keepOldParam) { Iterator paramNames = this.getSystemParams().keySet().iterator(); @@ -205,6 +246,16 @@ private void addFreePublicPages(IPage page, List pages) { } } + protected void updateReloadStatusResult() { + if (ApsWebApplicationUtils.getReloadInfo().containsKey(RELOAD_THREAD)) { + this.setReloadingResult(FAILURE_RELOADING_RESULT_CODE); + } else if (isReloadingErrorDetect()) { + this.setReloadingResult(WARNING_RELOADING_RESULT_CODE); + } else { + this.setReloadingResult(SUCCESS_RELOADING_RESULT_CODE); + } + } + protected ConfigInterface getConfigManager() { return _configManager; } @@ -230,7 +281,7 @@ public void setSystemParams(Map systemParams) { } public String getExternalParamMarker() { - return "_newParamMarker"; + return NEW_PARAM_MARKER; } private ConfigInterface _configManager; @@ -242,5 +293,7 @@ public String getExternalParamMarker() { public static final int FAILURE_RELOADING_RESULT_CODE = 0; public static final int SUCCESS_RELOADING_RESULT_CODE = 1; + public static final int PROGRESS_RELOADING_RESULT_CODE = 2; + public static final int WARNING_RELOADING_RESULT_CODE = 3; } diff --git a/src/main/java/com/agiletec/apsadmin/admin/baseAdmin.xml b/src/main/java/com/agiletec/apsadmin/admin/baseAdmin.xml index 1764e5b72..1c3f95674 100644 --- a/src/main/java/com/agiletec/apsadmin/admin/baseAdmin.xml +++ b/src/main/java/com/agiletec/apsadmin/admin/baseAdmin.xml @@ -7,6 +7,15 @@ + + + + + true + + + + admin.BaseAdmin.settings superuser @@ -16,11 +25,26 @@ admin.BaseAdmin.reloadConfigChoose superuser + - admin.BaseAdmin.reloadConfigResult + admin.BaseAdmin.reloadInProgress + admin.BaseAdmin.reloadConfigResult superuser + + admin.BaseAdmin.reloadConfigResult + admin.BaseAdmin.reloadInProgress + superuser + + + + + reloadProgress + + superuser + + admin.BaseAdmin.reloadEntitiesReferencesResult superuser @@ -47,4 +71,4 @@ - \ No newline at end of file + diff --git a/src/main/java/com/agiletec/apsadmin/admin/package_en.properties b/src/main/java/com/agiletec/apsadmin/admin/package_en.properties index 5f78a41e5..62f18435e 100644 --- a/src/main/java/com/agiletec/apsadmin/admin/package_en.properties +++ b/src/main/java/com/agiletec/apsadmin/admin/package_en.properties @@ -9,6 +9,7 @@ name.editor.ckeditor=CKEditor name.editor.hoofed=Hoofed (moo-Entando component) message.reloadConfig.ok=The configuration has been reloaded +message.reloadConfig.warning=Some services reported an error during the reload message.reloadConfig.ko=Something went wrong while reloading the configuration. Try again in a minute. message.reloadEntities.ok=Reloading Entity references message.configSystemParams.ok=The settings have been updated @@ -22,3 +23,11 @@ page.reloadConfig.help=The Reload Configuration section allows you to reload the title.entityManagement = Entities title.entityAdmin.manage = Entities title.entityAdmin.entityManagers.reload = Reload the references + + +reload.table.head.beanId=Service ID +reload.table.head.status=Status +reload.bean.status.ok=Success +reload.bean.status.ko=ERROR + +reload.legend.info=The information displayed depends on how the service was implemented. Any internal errors may not appear on this screen but are visible in the system logs. diff --git a/src/main/java/com/agiletec/apsadmin/admin/package_it.properties b/src/main/java/com/agiletec/apsadmin/admin/package_it.properties index 15ac32583..08c10413e 100644 --- a/src/main/java/com/agiletec/apsadmin/admin/package_it.properties +++ b/src/main/java/com/agiletec/apsadmin/admin/package_it.properties @@ -10,6 +10,7 @@ name.editor.ckeditor=CKEditor name.editor.hoofed=Hoofed (fa parte di moo-Entando) message.reloadConfig.ok=La configurazione di sistema è stata ricaricata +message.reloadConfig.warning=Durante il ricaricamento alcuni servizi hanno riportato un errore message.reloadConfig.ko=Non è stato possibile ricaricare la configurazione di sistema message.reloadEntities.ok=Il ricaricamento delle referenze delle Entità è in corso message.configSystemParams.ok=I cambiamenti sono stati salvati @@ -23,3 +24,10 @@ page.reloadConfig.help=Dalla sezione RICARICA CONFIGURAZIONE è possibile title.entityManagement = Entità title.entityAdmin.manage = Entità title.entityAdmin.entityManagers.reload = Ricarica le referenze + +reload.table.head.beanId=ID del servizio +reload.table.head.status=Stato +reload.bean.status.ok=Successo +reload.bean.status.ko=ERRORE + +reload.legend.info=le informazioni mostrate dipendono da come il servizio è stato implementato. Eventuali errori interni potrebbero non essere riportati in questa schermata, ma sono visibili solo a livello di log. diff --git a/src/main/java/com/agiletec/apsadmin/admin/reload/ReloadConfigThread.java b/src/main/java/com/agiletec/apsadmin/admin/reload/ReloadConfigThread.java new file mode 100644 index 000000000..f9049d820 --- /dev/null +++ b/src/main/java/com/agiletec/apsadmin/admin/reload/ReloadConfigThread.java @@ -0,0 +1,35 @@ +package com.agiletec.apsadmin.admin.reload; + +import com.agiletec.aps.util.ApsWebApplicationUtils; +import javax.servlet.http.HttpServletRequest; +import org.entando.entando.ent.util.EntLogging.EntLogFactory; +import org.slf4j.Logger; + +public class ReloadConfigThread extends Thread { + + public static final String RELOAD_THREAD = "RELOAD THREAD"; + + private final Logger log = EntLogFactory.getSanitizedLogger(ReloadConfigThread.class); + private final HttpServletRequest request; + + public ReloadConfigThread(final HttpServletRequest request) { + this.request = request; + } + + @Override + public void run() { + try { + ApsWebApplicationUtils.executeSystemRefresh(request); + log.info("ReloadConfigThread completed execution"); + } catch (InterruptedException e) { + ApsWebApplicationUtils.getReloadInfo().put(RELOAD_THREAD, e.getMessage()); + log.error("Thread interrupted", e); + Thread.currentThread().interrupt(); + } catch (Throwable e) { + ApsWebApplicationUtils.getReloadInfo().put(RELOAD_THREAD, e.getMessage()); + log.error("unexpected thread error", e); + Thread.currentThread().interrupt(); + } + } + +} diff --git a/src/main/java/com/agiletec/apsadmin/global-messages_en.properties b/src/main/java/com/agiletec/apsadmin/global-messages_en.properties index db9b3bcbb..1f9b5ee9a 100644 --- a/src/main/java/com/agiletec/apsadmin/global-messages_en.properties +++ b/src/main/java/com/agiletec/apsadmin/global-messages_en.properties @@ -28,6 +28,7 @@ label.preview=Preview label.remove=Delete label.refresh=Refresh label.reload=Reload +label.reload.check=verifica label.swap=Swap label.move=Move label.moveUp=Move up @@ -168,6 +169,8 @@ label.required=Required label.requiredFields=Required Fields label.message.seach=Search for existing label label.reload.confirm=Are you sure you want to reload the configuration? +label.reload.message.check=If the update does not occur, press the button below +label.reload.progress=Overall progress label.chooseYourCategoriesTreeStyle=Choose the style of the Category tree label.fullname=Full name label.bundleId=Bundle Id @@ -291,6 +294,7 @@ menu.languageAdmin.languages=Languages menu.languageAdmin.labels=Labels menu.reload.config=Reload the configuration +menu.reload.verify=Refresh the full status of the configuration reload menu.reload.contents=Reload the contents menu.entityAdmin=Entities @@ -406,6 +410,7 @@ message.title.referencedUsers=Users message.note.resolveReferences=Sorry. You cannot perform this action right now, you must first unlink the following cross-references. messages.error=Error messages.confirm=Success +messages.warning=Warning struts.messages.error.file.too.large=The file is too big. diff --git a/src/main/java/com/agiletec/apsadmin/global-messages_it.properties b/src/main/java/com/agiletec/apsadmin/global-messages_it.properties index 704b24ad3..f5b0bb6ed 100644 --- a/src/main/java/com/agiletec/apsadmin/global-messages_it.properties +++ b/src/main/java/com/agiletec/apsadmin/global-messages_it.properties @@ -29,6 +29,7 @@ label.preview=Anteprima label.remove=Elimina label.refresh=Aggiorna label.reload=Ricarica +label.reload.check=Aggiorna label.swap=Scambia label.move=Sposta @@ -174,6 +175,8 @@ label.required=Obbligatorio label.requiredFields=Campi obbligatori label.message.seach=Cerca per label esistente label.reload.confirm=Si e' sicuri di voler ricaricare la configurazione? +label.reload.message.check=In caso di mancato aggiornamento, premere il bottone sottostante +label.reload.progress=Percentuale completamento label.chooseYourCategoriesTreeStyle=Scegli lo stile dell''albero delle categorie label.fullname=Nome completo label.bundleId=Bundle Id @@ -299,6 +302,7 @@ menu.languageAdmin.labels=Etichette menu.reload=Ricarica menu.reload.config=Ricarica la configurazione +menu.reload.verify=Verifica stato caricamento menu.reload.contents=Ricarica i contenuti menu.contents.settings=Impostazione Contenuti @@ -415,6 +419,7 @@ message.title.referencedUsers=Utenti message.note.resolveReferences=Per poter portare a termine l''operazione richiesta, è necessario prima sciogliere le seguenti associazioni o riferimenti incrociati messages.error=Errore messages.confirm=Conferma +messages.warning=Attenzione struts.messages.error.file.too.large=File eccedente la dimensione massima consentita. diff --git a/src/main/java/com/agiletec/apsadmin/system/BaseAction.java b/src/main/java/com/agiletec/apsadmin/system/BaseAction.java index 1951a3741..80a81250f 100644 --- a/src/main/java/com/agiletec/apsadmin/system/BaseAction.java +++ b/src/main/java/com/agiletec/apsadmin/system/BaseAction.java @@ -57,7 +57,7 @@ protected boolean isCurrentUserMemberOf(String groupName) { /** * Check if the current user has the given permission granted. It always returns true if the - * user has the the "superuser" permission set in some role. + * user has the "superuser" permission set in some role. * @param permissionName The name of the permission to check against the current user. * @return true if the user has the permission granted, false otherwise. */ @@ -120,25 +120,24 @@ protected List getActualAllowedGroups() { } } } - Collections.sort(this._actualAllowedGroups, new BeanComparator("description")); + this._actualAllowedGroups.sort(new BeanComparator<>("description")); return this._actualAllowedGroups; } protected List getActualAllowedGroupCodes() { List codes = new ArrayList<>(); List groups = this.getActualAllowedGroups(); - for (int i = 0; i < groups.size(); i++) { - Group group = groups.get(i); - if (null != group && !codes.contains(group.getName())) { - codes.add(group.getName()); - } - } + for (Group group : groups) { + if (null != group && !codes.contains(group.getName())) { + codes.add(group.getName()); + } + } return codes; } /** * Return the current system language used in the back-end interface. If this language does not - * belong to those known by the system the default language is returned. A log line will + * belong to those known by the system, the default language is returned. A log line will * report the problem. * @return The current language. */ diff --git a/src/main/webapp/WEB-INF/apsadmin/jsp/admin/inc/reload-menu-intro.jsp b/src/main/webapp/WEB-INF/apsadmin/jsp/admin/inc/reload-menu-intro.jsp new file mode 100644 index 000000000..67119a754 --- /dev/null +++ b/src/main/webapp/WEB-INF/apsadmin/jsp/admin/inc/reload-menu-intro.jsp @@ -0,0 +1,32 @@ +<%@ taglib prefix="s" uri="/struts-tags" %> +<%@ taglib prefix="wp" uri="/aps-core" %> + + +

+
+ + + + +
+

+
+
+
+
+
diff --git a/src/main/webapp/WEB-INF/apsadmin/jsp/admin/reloadChoose.jsp b/src/main/webapp/WEB-INF/apsadmin/jsp/admin/reloadChoose.jsp index b60b1f44b..0c57c3e4d 100644 --- a/src/main/webapp/WEB-INF/apsadmin/jsp/admin/reloadChoose.jsp +++ b/src/main/webapp/WEB-INF/apsadmin/jsp/admin/reloadChoose.jsp @@ -1,5 +1,7 @@ <%@ taglib prefix="s" uri="/struts-tags" %> <%@ taglib prefix="wp" uri="/aps-core" %> +<%@ taglib prefix="wpsf" uri="/apsadmin-form"%> +