Merge pull request 'monitor_status' (!14) from monitor_status into master
Reviewed-on: #14
This commit is contained in:
commit
12646d3a8e
|
@ -1,5 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,7 +178,10 @@
|
||||||
|
|
||||||
|
|
||||||
<wb-module deploy-name="geoportal-data-entry-app-3.3.0">
|
<wb-module deploy-name="geoportal-data-entry-app-3.3.0">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,7 +357,10 @@
|
||||||
|
|
||||||
|
|
||||||
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,7 +536,10 @@
|
||||||
|
|
||||||
|
|
||||||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -703,7 +715,10 @@
|
||||||
|
|
||||||
|
|
||||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -831,19 +846,16 @@
|
||||||
|
|
||||||
|
|
||||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||||
<dependent-module archiveName="metadata-profile-form-builder-widget-2.2.1.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/metadata-profile-form-builder-widget/metadata-profile-form-builder-widget">
|
|
||||||
<dependency-type>uses</dependency-type>
|
|
||||||
</dependent-module>
|
|
||||||
<dependent-module archiveName="uri-resolver-manager-1.8.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/uri-resolver-manager/uri-resolver-manager">
|
|
||||||
<dependency-type>uses</dependency-type>
|
|
||||||
</dependent-module>
|
|
||||||
<dependent-module archiveName="geoportal-client-1.2.2.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/geoportal-client/geoportal-client">
|
<dependent-module archiveName="geoportal-client-1.2.2.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/geoportal-client/geoportal-client">
|
||||||
<dependency-type>uses</dependency-type>
|
<dependency-type>uses</dependency-type>
|
||||||
</dependent-module>
|
</dependent-module>
|
||||||
<dependent-module archiveName="geoportal-common-1.1.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/geoportal-common/geoportal-common">
|
<dependent-module archiveName="geoportal-common-1.1.1.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/geoportal-common/geoportal-common">
|
||||||
<dependency-type>uses</dependency-type>
|
<dependency-type>uses</dependency-type>
|
||||||
</dependent-module>
|
</dependent-module>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1019,7 +1031,10 @@
|
||||||
|
|
||||||
|
|
||||||
<property name="context-root" value="geoportal-data-entry-app"/>
|
<property name="context-root" value="geoportal-data-entry-app"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1195,7 +1210,10 @@
|
||||||
|
|
||||||
|
|
||||||
<property name="java-output-path" value="/geoportal-data-entry-app/target/geoportal-data-entry-app-2.0.0-SNAPSHOT/WEB-INF/classes"/>
|
<property name="java-output-path" value="/geoportal-data-entry-app/target/geoportal-data-entry-app-2.0.0-SNAPSHOT/WEB-INF/classes"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1371,7 +1389,10 @@
|
||||||
|
|
||||||
|
|
||||||
</wb-module>
|
</wb-module>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [v3.3.0] - 2024-06-28
|
## [v3.3.0-SNAPSHOT] - 2024-06-28
|
||||||
|
|
||||||
- Implemented the init facility to resolve a public link on an item [#27120]
|
- Implemented the init facility to resolve a public link on an item [#27120]
|
||||||
- Integrated new Uri-Resolver-Manager [#27160]
|
- Integrated new Uri-Resolver-Manager [#27160]
|
||||||
- Added Get Shareable Link facility [#27120]
|
- Added Get Shareable Link facility [#27120]
|
||||||
- Added optional message when performing lifecycle step [#27192]
|
- Added optional message when performing lifecycle step [#27192]
|
||||||
- Enforced deleteProject method/UX
|
- Enforced deleteProject method/UX
|
||||||
|
- The save operation is now monitored asynchronously [#28268]
|
||||||
|
|
||||||
## [v3.2.2] - 2024-01-11
|
## [v3.2.2] - 2024-01-11
|
||||||
|
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -14,7 +14,7 @@
|
||||||
<groupId>org.gcube.portlets.user</groupId>
|
<groupId>org.gcube.portlets.user</groupId>
|
||||||
<artifactId>geoportal-data-entry-app</artifactId>
|
<artifactId>geoportal-data-entry-app</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
<version>3.3.0</version>
|
<version>3.3.0-SNAPSHOT</version>
|
||||||
<name>GeoPortal Data Entry App</name>
|
<name>GeoPortal Data Entry App</name>
|
||||||
<description>The GeoPortal Data Entry App is an application to build the web forms for data entries needed to create projects/documents (based on UCD) in the D4Science Geoportal service</description>
|
<description>The GeoPortal Data Entry App is an application to build the web forms for data entries needed to create projects/documents (based on UCD) in the D4Science Geoportal service</description>
|
||||||
<scm>
|
<scm>
|
||||||
|
|
|
@ -72,6 +72,7 @@ import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil.HTML_TAG;
|
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil.HTML_TAG;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon;
|
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.ModalConfirm;
|
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.ModalConfirm;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.UUIDUtil;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport;
|
import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
||||||
|
@ -79,6 +80,8 @@ import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.ProjectNotFoundException;
|
import org.gcube.portlets.user.geoportaldataentry.shared.ProjectNotFoundException;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.UserRights;
|
import org.gcube.portlets.user.geoportaldataentry.shared.UserRights;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringActionsOnClient;
|
||||||
import org.gcube.portlets.widgets.gdvw.client.GeoportalDataViewerWidget;
|
import org.gcube.portlets.widgets.gdvw.client.GeoportalDataViewerWidget;
|
||||||
import org.gcube.portlets.widgets.gdvw.client.project.ProjectViewer;
|
import org.gcube.portlets.widgets.gdvw.client.project.ProjectViewer;
|
||||||
import org.gcube.portlets.widgets.mpformbuilder.client.MetadataProfileFormBuilderServiceAsync;
|
import org.gcube.portlets.widgets.mpformbuilder.client.MetadataProfileFormBuilderServiceAsync;
|
||||||
|
@ -93,9 +96,13 @@ import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote
|
||||||
|
|
||||||
import com.github.gwtbootstrap.client.ui.Alert;
|
import com.github.gwtbootstrap.client.ui.Alert;
|
||||||
import com.github.gwtbootstrap.client.ui.Button;
|
import com.github.gwtbootstrap.client.ui.Button;
|
||||||
|
import com.github.gwtbootstrap.client.ui.Icon;
|
||||||
|
import com.github.gwtbootstrap.client.ui.Label;
|
||||||
import com.github.gwtbootstrap.client.ui.Modal;
|
import com.github.gwtbootstrap.client.ui.Modal;
|
||||||
import com.github.gwtbootstrap.client.ui.constants.AlertType;
|
import com.github.gwtbootstrap.client.ui.constants.AlertType;
|
||||||
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
|
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
|
||||||
|
import com.github.gwtbootstrap.client.ui.constants.IconSize;
|
||||||
|
import com.github.gwtbootstrap.client.ui.constants.IconType;
|
||||||
import com.github.gwtbootstrap.client.ui.constants.LabelType;
|
import com.github.gwtbootstrap.client.ui.constants.LabelType;
|
||||||
import com.google.gwt.core.client.EntryPoint;
|
import com.google.gwt.core.client.EntryPoint;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
|
@ -117,7 +124,6 @@ import com.google.gwt.user.client.ui.FlowPanel;
|
||||||
import com.google.gwt.user.client.ui.HTML;
|
import com.google.gwt.user.client.ui.HTML;
|
||||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||||
import com.google.gwt.user.client.ui.Image;
|
import com.google.gwt.user.client.ui.Image;
|
||||||
import com.google.gwt.user.client.ui.Label;
|
|
||||||
import com.google.gwt.user.client.ui.RootPanel;
|
import com.google.gwt.user.client.ui.RootPanel;
|
||||||
import com.google.gwt.user.client.ui.TreeItem;
|
import com.google.gwt.user.client.ui.TreeItem;
|
||||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
|
@ -178,6 +184,8 @@ public class GeoPortalDataEntryApp implements EntryPoint {
|
||||||
|
|
||||||
private GNADataEntryExtendedConfigProfile gNADataEntryPresentationConfig = null;
|
private GNADataEntryExtendedConfigProfile gNADataEntryPresentationConfig = null;
|
||||||
|
|
||||||
|
private MonitoringActionsOnClient monitorActionsClientInstance = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the entry point method.
|
* This is the entry point method.
|
||||||
*/
|
*/
|
||||||
|
@ -441,6 +449,7 @@ public class GeoPortalDataEntryApp implements EntryPoint {
|
||||||
mainTabPanel.setTabActive(1);
|
mainTabPanel.setTabActive(1);
|
||||||
} else
|
} else
|
||||||
mainTabPanel.setTabActive(0);
|
mainTabPanel.setTabActive(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -456,9 +465,19 @@ public class GeoPortalDataEntryApp implements EntryPoint {
|
||||||
initExecutor.putCommand(commandInitOnItem);
|
initExecutor.putCommand(commandInitOnItem);
|
||||||
}
|
}
|
||||||
initExecutor.execute();
|
initExecutor.execute();
|
||||||
|
|
||||||
|
// Uncomment this to test the monitor
|
||||||
|
// try {
|
||||||
|
// new Timer() {
|
||||||
|
// public void run() {
|
||||||
|
// appManagerBus.fireEvent(new SaveGeonaDataFormsEvent("the id", null));
|
||||||
|
// }
|
||||||
|
// }.schedule(7000);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// }
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO Auto-generated catch block
|
Window.alert(
|
||||||
e.printStackTrace();
|
"Error during application initialization. Please refresh and try again. If the problem persists please contact the support");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -717,98 +736,268 @@ public class GeoPortalDataEntryApp implements EntryPoint {
|
||||||
@Override
|
@Override
|
||||||
public void onSave(final SaveGeonaDataFormsEvent saveGeonaDataFormsEvent) {
|
public void onSave(final SaveGeonaDataFormsEvent saveGeonaDataFormsEvent) {
|
||||||
|
|
||||||
|
GWT.log("SaveGeonaDataFormsEvent fired");
|
||||||
|
|
||||||
|
// resetting last monitor
|
||||||
|
monitorActionsClientInstance = null;
|
||||||
|
|
||||||
geoNaMainForm.enableButtonSave(false);
|
geoNaMainForm.enableButtonSave(false);
|
||||||
|
|
||||||
if (saveGeonaDataFormsEvent.getTreeNode() != null) {
|
// TODO REMOVE THIS
|
||||||
|
if (saveGeonaDataFormsEvent.getTreeNode() == null) {
|
||||||
final Modal modal = new Modal(true);
|
Window.alert("I cannot save the project. Incorrect data. Please, refresh and try again");
|
||||||
modal.setCloseVisible(false);
|
|
||||||
modal.setTitle("Saving project...");
|
|
||||||
modal.hide(false);
|
|
||||||
modal.setWidth(800);
|
|
||||||
modal.setMaxHeigth("650px");
|
|
||||||
final VerticalPanel modalContainerPanel = new VerticalPanel();
|
|
||||||
final LoaderIcon loader = new LoaderIcon();
|
|
||||||
loader.setText("Trying to save the data, please wait...");
|
|
||||||
modalContainerPanel.add(loader);
|
|
||||||
modal.add(modalContainerPanel);
|
|
||||||
|
|
||||||
String[] listPostActionOnSave = mainTabPanel
|
|
||||||
.getPostCreationActionOnSave(saveGeonaDataFormsEvent.getProfileID());
|
|
||||||
|
|
||||||
List<String> stepsOnPostCreation = new ArrayList<String>();
|
|
||||||
if (listPostActionOnSave != null) {
|
|
||||||
for (String step : listPostActionOnSave) {
|
|
||||||
stepsOnPostCreation.add(step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GWT.log("Calling saveGeonaDataForms, stepsOnPostCreation are " + stepsOnPostCreation);
|
|
||||||
|
|
||||||
GeoportalDataEntryServiceAsync.Util.getInstance().saveGeonaDataForms(
|
|
||||||
saveGeonaDataFormsEvent.getProfileID(), saveGeonaDataFormsEvent.getTreeNode(),
|
|
||||||
stepsOnPostCreation, new AsyncCallback<CommitReport>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable caught) {
|
|
||||||
modalContainerPanel.clear();
|
|
||||||
modal.setCloseVisible(true);
|
|
||||||
try {
|
|
||||||
modal.remove(loader);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
Alert alert = new Alert(caught.getMessage());
|
|
||||||
alert.setType(AlertType.ERROR);
|
|
||||||
alert.setClose(false);
|
|
||||||
modal.add(alert);
|
|
||||||
// resetUI();
|
|
||||||
geoNaMainForm.enableButtonSave(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(CommitReport result) {
|
|
||||||
modalContainerPanel.clear();
|
|
||||||
modal.setCloseVisible(true);
|
|
||||||
modal.setTitle("Project Saved!");
|
|
||||||
|
|
||||||
LifecycleInformationDV lcDV = result.getLifecycleInformation();
|
|
||||||
|
|
||||||
switch (lcDV.getLastOperationStatus()) {
|
|
||||||
case OK: {
|
|
||||||
String success = HTMLUtil.getHTMLElement(HTML_TAG.span, 14, "32CD32", null,
|
|
||||||
"SUCCESS");
|
|
||||||
String msg = lcDV.getLastInvokedStep() + "terminated with: " + success;
|
|
||||||
projectSavedWithSuccess = true;
|
|
||||||
geoNaMainForm.showAlertOnSaveAction(msg, AlertType.SUCCESS, true);
|
|
||||||
purgeFileUploaded();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WARNING: {
|
|
||||||
geoNaMainForm.enableButtonSave(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ERROR: {
|
|
||||||
geoNaMainForm.enableButtonSave(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
savedMap.put(result.getProjectID(), saveGeonaDataFormsEvent.getTreeNode());
|
|
||||||
|
|
||||||
LifecycleInformationPanel lip = new LifecycleInformationPanel(result.getProjectID(),
|
|
||||||
result.getProfileID(), result.getProjectAsJSON(), lcDV, false);
|
|
||||||
|
|
||||||
modalContainerPanel.add(lip);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
modal.show();
|
|
||||||
} else
|
|
||||||
geoNaMainForm.enableButtonSave(true);
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Modal modal = new Modal(true);
|
||||||
|
modal.setCloseVisible(false);
|
||||||
|
modal.setTitle("Saving project...");
|
||||||
|
modal.hide(false);
|
||||||
|
modal.setWidth(800);
|
||||||
|
modal.setMaxHeigth("650px");
|
||||||
|
final VerticalPanel modalContainerPanel = new VerticalPanel();
|
||||||
|
final VerticalPanel modalContainerMonitor = new VerticalPanel();
|
||||||
|
final LoaderIcon loader = new LoaderIcon();
|
||||||
|
loader.setText("Trying to save the project, please wait...");
|
||||||
|
modalContainerPanel.add(loader);
|
||||||
|
modalContainerPanel.add(modalContainerMonitor);
|
||||||
|
modal.add(modalContainerPanel);
|
||||||
|
|
||||||
|
String[] listPostActionOnSave = mainTabPanel
|
||||||
|
.getPostCreationActionOnSave(saveGeonaDataFormsEvent.getProfileID());
|
||||||
|
|
||||||
|
List<String> stepsOnPostCreation = new ArrayList<String>();
|
||||||
|
if (listPostActionOnSave != null) {
|
||||||
|
for (String step : listPostActionOnSave) {
|
||||||
|
stepsOnPostCreation.add(step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GWT.log("Calling saveGeonaDataForms, stepsOnPostCreation are " + stepsOnPostCreation);
|
||||||
|
|
||||||
|
final String uuid = UUIDUtil.generateUUID();
|
||||||
|
GeoportalDataEntryServiceAsync.Util.getInstance().saveGeonaDataForms(uuid,
|
||||||
|
saveGeonaDataFormsEvent.getProfileID(), saveGeonaDataFormsEvent.getTreeNode(),
|
||||||
|
stepsOnPostCreation, new AsyncCallback<Void>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable caught) {
|
||||||
|
modalContainerPanel.clear();
|
||||||
|
modal.setCloseVisible(true);
|
||||||
|
try {
|
||||||
|
modal.remove(loader);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
Alert alert = new Alert(caught.getMessage());
|
||||||
|
alert.setType(AlertType.ERROR);
|
||||||
|
alert.setClose(false);
|
||||||
|
modal.add(alert);
|
||||||
|
// resetUI();
|
||||||
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Void result) {
|
||||||
|
// null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.show();
|
||||||
|
|
||||||
|
// Monitoring the save actions calling the timer (polling)
|
||||||
|
String uuidString = uuid.toString();
|
||||||
|
final Timer pollingMonitor = new Timer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
if (!GWT.isProdMode()) {
|
||||||
|
GWT.log("New polling starts...");
|
||||||
|
if (monitorActionsClientInstance != null) {
|
||||||
|
GWT.log("New polling for: " + monitorActionsClientInstance.getMonitorUUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the last action on monitor has been consumed on client side
|
||||||
|
boolean monitorConsumedByClient = false;
|
||||||
|
|
||||||
|
if (monitorActionsClientInstance != null) {
|
||||||
|
|
||||||
|
// In case of exception or terminated monitor on server side, I'm going to
|
||||||
|
// cancel the monitor on client side (last monitor has been consumed)
|
||||||
|
if (monitorActionsClientInstance.getException() != null
|
||||||
|
|| monitorActionsClientInstance.isMonitoringTerminatedOnServer()) {
|
||||||
|
monitorConsumedByClient = true;
|
||||||
|
// cancel the monitor client side
|
||||||
|
GWT.log("Cancelled the monitor polling for: "
|
||||||
|
+ monitorActionsClientInstance.getMonitorUUID());
|
||||||
|
cancel();
|
||||||
|
modal.setCloseVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean isMonitorConsumedByClient = monitorConsumedByClient;
|
||||||
|
|
||||||
|
GeoportalDataEntryServiceAsync.Util.getInstance().getSavingProjectMonitorStatus(uuidString,
|
||||||
|
monitorConsumedByClient, new AsyncCallback<MonitoringActionsOnClient>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable caught) {
|
||||||
|
|
||||||
|
if (isMonitorConsumedByClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modalContainerPanel.clear();
|
||||||
|
modal.setCloseVisible(true);
|
||||||
|
try {
|
||||||
|
modal.remove(loader);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
Alert alert = new Alert(caught.getMessage());
|
||||||
|
alert.setType(AlertType.ERROR);
|
||||||
|
alert.setClose(false);
|
||||||
|
modal.add(alert);
|
||||||
|
// resetUI();
|
||||||
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(MonitoringActionsOnClient monitoringActions) {
|
||||||
|
|
||||||
|
// The monitor is consumed here reporting the actions
|
||||||
|
monitorActionsClientInstance = monitoringActions;
|
||||||
|
|
||||||
|
if (isMonitorConsumedByClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitoringActions != null && monitoringActions.getMonitor() != null) {
|
||||||
|
modalContainerMonitor.clear();
|
||||||
|
modalContainerMonitor.getElement().getStyle().setMarginTop(15, Unit.PX);
|
||||||
|
LinkedHashMap<Integer, MonitoringAction> monitor = monitoringActions
|
||||||
|
.getMonitor();
|
||||||
|
if (monitor.size() > 0) {
|
||||||
|
for (Integer key : monitor.keySet()) {
|
||||||
|
MonitoringAction action = monitor.get(key);
|
||||||
|
Icon icon = null;
|
||||||
|
if (action.getStatus() != null) {
|
||||||
|
switch (action.getStatus()) {
|
||||||
|
case IN_PENDING:
|
||||||
|
icon = new Icon(IconType.HEADPHONES);
|
||||||
|
icon.setTitle(action.getStatus().getLabel());
|
||||||
|
icon.setSize(IconSize.TWO_TIMES);
|
||||||
|
break;
|
||||||
|
case IN_PROGESS:
|
||||||
|
icon = new Icon(IconType.GEAR);
|
||||||
|
icon.setSpin(true);
|
||||||
|
icon.setSize(IconSize.TWO_TIMES);
|
||||||
|
icon.setTitle(action.getStatus().getLabel());
|
||||||
|
break;
|
||||||
|
case DONE:
|
||||||
|
icon = new Icon(IconType.OK);
|
||||||
|
icon.getElement().getStyle().setColor("#008000");
|
||||||
|
icon.setSize(IconSize.TWO_TIMES);
|
||||||
|
icon.setTitle(action.getStatus().getLabel());
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
icon = new Icon(IconType.WARNING_SIGN);
|
||||||
|
icon.getElement().getStyle().setColor("#FF0000");
|
||||||
|
icon.setSize(IconSize.TWO_TIMES);
|
||||||
|
icon.setTitle(action.getStatus().getLabel());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalPanel hp = new HorizontalPanel();
|
||||||
|
hp.getElement().getStyle().setMargin(10, Unit.PX);
|
||||||
|
hp.getElement().getStyle().setMarginLeft(32, Unit.PX);
|
||||||
|
com.google.gwt.user.client.ui.Label label = new com.google.gwt.user.client.ui.Label(
|
||||||
|
action.getMsg());
|
||||||
|
icon.getElement().getStyle().setMarginRight(10, Unit.PX);
|
||||||
|
|
||||||
|
if (icon != null)
|
||||||
|
hp.add(icon);
|
||||||
|
|
||||||
|
hp.add(label);
|
||||||
|
|
||||||
|
modalContainerMonitor.add(hp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitoringActions.getException() != null) {
|
||||||
|
modalContainerPanel.clear();
|
||||||
|
modal.setCloseVisible(true);
|
||||||
|
try {
|
||||||
|
modal.remove(loader);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
Alert alert = new Alert(monitoringActions.getException().getMessage());
|
||||||
|
alert.setType(AlertType.ERROR);
|
||||||
|
alert.setClose(false);
|
||||||
|
modal.add(alert);
|
||||||
|
// resetUI();
|
||||||
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommitReport commitReport = monitoringActions.getCommitReport();
|
||||||
|
if (commitReport != null) {
|
||||||
|
modalContainerPanel.clear();
|
||||||
|
modal.setCloseVisible(true);
|
||||||
|
modal.setTitle("Project Saved!");
|
||||||
|
|
||||||
|
LifecycleInformationDV lcDV = commitReport.getLifecycleInformation();
|
||||||
|
|
||||||
|
switch (lcDV.getLastOperationStatus()) {
|
||||||
|
case OK: {
|
||||||
|
String success = HTMLUtil.getHTMLElement(HTML_TAG.span, 14,
|
||||||
|
"32CD32", null, "SUCCESS");
|
||||||
|
String msg = lcDV.getLastInvokedStep() + "terminated with: "
|
||||||
|
+ success;
|
||||||
|
projectSavedWithSuccess = true;
|
||||||
|
geoNaMainForm.showAlertOnSaveAction(msg, AlertType.SUCCESS, true);
|
||||||
|
purgeFileUploaded();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WARNING: {
|
||||||
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR: {
|
||||||
|
geoNaMainForm.enableButtonSave(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
savedMap.put(commitReport.getProjectID(),
|
||||||
|
saveGeonaDataFormsEvent.getTreeNode());
|
||||||
|
|
||||||
|
LifecycleInformationPanel lip = new LifecycleInformationPanel(
|
||||||
|
commitReport.getProjectID(), commitReport.getProfileID(),
|
||||||
|
commitReport.getProjectAsJSON(), lcDV, false);
|
||||||
|
|
||||||
|
modalContainerPanel.add(lip);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pollingMonitor.scheduleRepeating(1500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedCon
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringActionsOnClient;
|
||||||
|
|
||||||
import com.google.gwt.user.client.rpc.RemoteService;
|
import com.google.gwt.user.client.rpc.RemoteService;
|
||||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||||
|
@ -39,13 +40,14 @@ public interface GeoportalDataEntryService extends RemoteService {
|
||||||
/**
|
/**
|
||||||
* Save geona data forms.
|
* Save geona data forms.
|
||||||
*
|
*
|
||||||
|
* @param uuid the uuid
|
||||||
* @param profileID the profile ID
|
* @param profileID the profile ID
|
||||||
* @param tree_Node the tree node
|
* @param tree_Node the tree node
|
||||||
* @param stepsOnPostCreation the steps on post creation
|
* @param stepsOnPostCreation the steps on post creation
|
||||||
* @return the commit report
|
* @return the commit report
|
||||||
* @throws Exception the exception
|
* @throws Exception the exception
|
||||||
*/
|
*/
|
||||||
CommitReport saveGeonaDataForms(String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
void saveGeonaDataForms(String uuid, String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
||||||
List<String> stepsOnPostCreation) throws Exception;
|
List<String> stepsOnPostCreation) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,6 +148,7 @@ public interface GeoportalDataEntryService extends RemoteService {
|
||||||
* @param optionalMessage the optional message
|
* @param optionalMessage the optional message
|
||||||
* @param action the action
|
* @param action the action
|
||||||
* @return the project DV
|
* @return the project DV
|
||||||
|
* @throws Exception the exception
|
||||||
*/
|
*/
|
||||||
StepPerformedResultDV performActionSteps(String profileID, String projectID, String optionalMessage, ActionDefinitionDV action) throws Exception;
|
StepPerformedResultDV performActionSteps(String profileID, String projectID, String optionalMessage, ActionDefinitionDV action) throws Exception;
|
||||||
|
|
||||||
|
@ -248,4 +251,16 @@ public interface GeoportalDataEntryService extends RemoteService {
|
||||||
*/
|
*/
|
||||||
ProjectView getProjectView(String profileID, String projectID) throws Exception;
|
ProjectView getProjectView(String profileID, String projectID) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the saving project monitor status.
|
||||||
|
*
|
||||||
|
* @param monitorUUID the monitor UUID
|
||||||
|
* @param isMonitoringTerminatedClientConsumed the is monitoring terminated client consumed
|
||||||
|
* @return the saving project monitor status
|
||||||
|
* @throws Exception the exception
|
||||||
|
*/
|
||||||
|
MonitoringActionsOnClient getSavingProjectMonitorStatus(String monitorUUID,
|
||||||
|
boolean isMonitoringTerminatedClientConsumed) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedCon
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringActionsOnClient;
|
||||||
|
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
@ -53,8 +54,8 @@ public interface GeoportalDataEntryServiceAsync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveGeonaDataForms(String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
void saveGeonaDataForms(String uuid, String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
||||||
List<String> stepsOnPostCreation, AsyncCallback<CommitReport> callback);
|
List<String> stepsOnPostCreation, AsyncCallback<Void> callback);
|
||||||
|
|
||||||
void updateGeportalDataForm(String profileID, String projectID, GeoNaFormDataObject section,
|
void updateGeportalDataForm(String profileID, String projectID, GeoNaFormDataObject section,
|
||||||
String sectionPath, List<FilePathDV> listFilePaths, AsyncCallback<CommitReport> callback);
|
String sectionPath, List<FilePathDV> listFilePaths, AsyncCallback<CommitReport> callback);
|
||||||
|
@ -101,4 +102,7 @@ public interface GeoportalDataEntryServiceAsync {
|
||||||
|
|
||||||
void getProjectView(String profileID, String projectID, AsyncCallback<ProjectView> callback);
|
void getProjectView(String profileID, String projectID, AsyncCallback<ProjectView> callback);
|
||||||
|
|
||||||
|
void getSavingProjectMonitorStatus(String monitorUUID, boolean isMonitoringTerminatedClientConsumed,
|
||||||
|
AsyncCallback<MonitoringActionsOnClient> callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.client.ui.utils;
|
||||||
|
|
||||||
|
import com.github.gwtbootstrap.client.ui.Modal;
|
||||||
|
import com.github.gwtbootstrap.client.ui.event.HideEvent;
|
||||||
|
import com.github.gwtbootstrap.client.ui.event.HideHandler;
|
||||||
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.core.client.Scheduler;
|
||||||
|
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||||
|
import com.google.gwt.dom.client.Element;
|
||||||
|
import com.google.gwt.user.client.DOM;
|
||||||
|
import com.google.gwt.user.client.Event;
|
||||||
|
import com.google.gwt.user.client.EventListener;
|
||||||
|
import com.google.gwt.user.client.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class ExtModal.
|
||||||
|
*
|
||||||
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||||
|
*
|
||||||
|
* Apr 29, 2021
|
||||||
|
*
|
||||||
|
* This Class extends the {{@link Modal} preventing the default close of
|
||||||
|
* the Modal Bootstrap when clicking outside of the modal Window
|
||||||
|
*/
|
||||||
|
public class ExtModal extends Modal {
|
||||||
|
|
||||||
|
private String elementId;
|
||||||
|
private String closeElementId;
|
||||||
|
private Boolean closeButtoClicked = false;
|
||||||
|
final private ExtModal INSTANCE = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new ext modal.
|
||||||
|
*/
|
||||||
|
public ExtModal() {
|
||||||
|
super();
|
||||||
|
setElementIds();
|
||||||
|
addDeferredCommandToPreventModalClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty, hidden widget with specified show behavior.
|
||||||
|
*
|
||||||
|
* @param animated <code>true</code> if the widget should be animated.
|
||||||
|
*/
|
||||||
|
public ExtModal(boolean animated) {
|
||||||
|
super(animated, false);
|
||||||
|
setElementIds();
|
||||||
|
addDeferredCommandToPreventModalClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty, hidden widget with specified show behavior.
|
||||||
|
*
|
||||||
|
* @param animated <code>true</code> if the widget should be animated.
|
||||||
|
* @param dynamicSafe <code>true</code> removes from RootPanel when hidden
|
||||||
|
*/
|
||||||
|
public ExtModal(boolean animated, boolean dynamicSafe) {
|
||||||
|
super(animated, dynamicSafe);
|
||||||
|
setElementIds();
|
||||||
|
addDeferredCommandToPreventModalClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDeferredCommandToPreventModalClose() {
|
||||||
|
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
((Element) INSTANCE.getElement().getChildNodes().getItem(0)).getFirstChildElement()
|
||||||
|
.setId(closeElementId);
|
||||||
|
preventModalCloseWhenClickingOutside();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the element id.
|
||||||
|
*/
|
||||||
|
private void setElementIds() {
|
||||||
|
this.elementId = "my-modal-publish-meta" + Random.nextInt();
|
||||||
|
this.getElement().setId(elementId);
|
||||||
|
|
||||||
|
this.closeElementId = "my-modal-close-button" + Random.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent modal close when clicking outside.
|
||||||
|
*/
|
||||||
|
private void preventModalCloseWhenClickingOutside() {
|
||||||
|
|
||||||
|
com.google.gwt.user.client.Element buttonCloseElement = DOM.getElementById(this.closeElementId);
|
||||||
|
|
||||||
|
if (buttonCloseElement != null) {
|
||||||
|
|
||||||
|
Event.sinkEvents(buttonCloseElement, Event.ONCLICK);
|
||||||
|
Event.setEventListener(buttonCloseElement, new EventListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBrowserEvent(Event event) {
|
||||||
|
if (Event.ONCLICK == event.getTypeInt()) {
|
||||||
|
GWT.log("close event clicked");
|
||||||
|
closeButtoClicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
GWT.log("button close element not found");
|
||||||
|
closeButtoClicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide any popup panel opened
|
||||||
|
this.addHideHandler(new HideHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHide(HideEvent hideEvent) {
|
||||||
|
GWT.log("HideEvent on modal fired");
|
||||||
|
GWT.log(hideEvent.toDebugString());
|
||||||
|
GWT.log("CloseButtonClicked is: " + closeButtoClicked);
|
||||||
|
|
||||||
|
if (!closeButtoClicked) {
|
||||||
|
hideEvent.preventDefault();
|
||||||
|
hideEvent.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.client.ui.utils;
|
||||||
|
|
||||||
|
public class UUIDUtil {
|
||||||
|
|
||||||
|
public static String generateUUID() {
|
||||||
|
return nativeGenerateUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usa una funzione JavaScript per generare un UUID
|
||||||
|
private static native String nativeGenerateUUID() /*-{
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||||
|
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}-*/;
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
@ -76,6 +77,9 @@ import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.ProjectNotFoundException;
|
import org.gcube.portlets.user.geoportaldataentry.shared.ProjectNotFoundException;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
||||||
import org.gcube.portlets.user.geoportaldataentry.shared.UserRights;
|
import org.gcube.portlets.user.geoportaldataentry.shared.UserRights;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction.STATUS;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringActionsOnClient;
|
||||||
import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean;
|
import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean;
|
||||||
import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded;
|
import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded;
|
||||||
import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote;
|
import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote;
|
||||||
|
@ -137,88 +141,139 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
/**
|
/**
|
||||||
* Save geona data forms.
|
* Save geona data forms.
|
||||||
*
|
*
|
||||||
|
* @param uuid the uuid
|
||||||
* @param profileID the profile ID
|
* @param profileID the profile ID
|
||||||
* @param optionalMessage the optional message
|
|
||||||
* @param tree_Node the tree node
|
* @param tree_Node the tree node
|
||||||
* @param stepsOnPostCreation the steps on post creation
|
* @param stepsOnPostCreation the steps on post creation
|
||||||
* @return the commit report
|
* @return the commit report
|
||||||
* @throws Exception the exception
|
* @throws Exception the exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CommitReport saveGeonaDataForms(String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
public void saveGeonaDataForms(String uuid, String profileID, Tree_Node<GeoNaFormDataObject> tree_Node,
|
||||||
List<String> stepsOnPostCreation) throws Exception {
|
List<String> stepsOnPostCreation) throws Exception {
|
||||||
LOG.info("saveGeonaDataForms called for profileID {}", profileID);
|
LOG.info("saveGeonaDataForms called for profileID {}", profileID);
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
LOG.info("Procedure starting at: " + startTime);
|
LOG.info("Procedure starting at: " + startTime);
|
||||||
|
final String uuidAsString = uuid.toString();
|
||||||
|
|
||||||
MongoServiceUtil mongoService = new MongoServiceUtil();
|
// Uncomment this to test the monitor
|
||||||
String theDocumentString = null;
|
// if(!SessionUtil.isIntoPortal()) {
|
||||||
try {
|
// MockData.mockMonitor(uuidAsString, getThreadLocalRequest());
|
||||||
|
// return;
|
||||||
FormDataObjectToJSON metadataConverter = new FormDataObjectToJSON();
|
// }
|
||||||
JSONObject theDocument = metadataConverter.convert(tree_Node, null);
|
|
||||||
theDocumentString = theDocument.toString();
|
|
||||||
LOG.info("Got Document: " + theDocumentString);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.error("Error on converting form data: ", e);
|
|
||||||
throw new Exception(
|
|
||||||
"Error occurred on converting data, try again or contact the support. Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
final MonitoringActionsOnServer monitoringActionsOnServer = new MonitoringActionsOnServer(
|
||||||
|
this.getThreadLocalRequest(), uuidAsString);
|
||||||
|
List<File> listTempDirs = new ArrayList<File>();
|
||||||
Project theProject = null;
|
Project theProject = null;
|
||||||
try {
|
try {
|
||||||
|
MongoServiceUtil mongoService = new MongoServiceUtil();
|
||||||
|
String theDocumentString = null;
|
||||||
|
try {
|
||||||
|
// // 1. Action to Monitoring
|
||||||
|
// MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
// "Converting project metadata to Geoportal data model");
|
||||||
|
// action = monitoringActionsOnServer.pushAction(action);
|
||||||
|
|
||||||
SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true);
|
FormDataObjectToJSON metadataConverter = new FormDataObjectToJSON();
|
||||||
LOG.debug("Going to create the project...");
|
JSONObject theDocument = metadataConverter.convert(tree_Node, null);
|
||||||
theProject = mongoService.createNew(profileID, theDocumentString);
|
|
||||||
LOG.info("Project created with id: " + theProject.getId() + " and profileID: " + theProject.getProfileID());
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
// // 1. Action completed
|
||||||
LOG.error("Error on creating the project: ", e);
|
// action.setMsg("Converted project metadata to Geoportal data model");
|
||||||
throw new Exception("Error occurred on creating new project, try again or contact the support. Error: "
|
// action.setStatus(STATUS.DONE);
|
||||||
+ e.getMessage());
|
// monitoringActionsOnServer.overrideAction(action);
|
||||||
}
|
|
||||||
|
|
||||||
List<File> listTempDirs = new ArrayList<File>();
|
theDocumentString = theDocument.toString();
|
||||||
|
LOG.info("Got Document: " + theDocumentString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error on converting form data: ", e);
|
||||||
|
throw new Exception("Error occurred on converting data, try again or contact the support. Error: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Uploading files into tempDirs in order to avoid clashing of names
|
SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true);
|
||||||
LOG.debug("Going to upload the files");
|
LOG.debug("Going to create the project...");
|
||||||
listTempDirs = recursiveUploadFileset(mongoService, profileID, theProject, tree_Node, null, listTempDirs);
|
// 2. Action to Monitoring
|
||||||
|
MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
"Creating the project on the Geoportal storage service");
|
||||||
|
action = monitoringActionsOnServer.pushAction(action);
|
||||||
|
|
||||||
} catch (Exception e) {
|
theProject = mongoService.createNew(profileID, theDocumentString);
|
||||||
LOG.error("Error on uploading files: ", e);
|
|
||||||
throw new Exception(
|
|
||||||
"Error occurred on uploading files, try again or contact the support. Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
// 2. Action completed
|
||||||
|
action.setMsg("Created the project on the Geoportal storage service");
|
||||||
|
action.setStatus(STATUS.DONE);
|
||||||
|
monitoringActionsOnServer.overrideAction(action);
|
||||||
|
|
||||||
ProjectsCaller client = GeoportalClientCaller.projects();
|
LOG.info("Project created with id: " + theProject.getId() + " and profileID: "
|
||||||
SessionUtil.getCurrentContext(getThreadLocalRequest(), true);
|
+ theProject.getProfileID());
|
||||||
LOG.info("stepsOnPostCreation are {}", stepsOnPostCreation);
|
|
||||||
for (String stepID : stepsOnPostCreation) {
|
} catch (Exception e) {
|
||||||
LOG.info("calling step OnPostCreation are {}", stepID);
|
LOG.error("Error on creating the project: ", e);
|
||||||
theProject = client.performStep(theProject.getProfileID(), theProject.getId(), stepID, null, null);
|
throw new Exception("Error occurred on creating new project, try again or contact the support. Error: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Uploading files into tempDirs in order to avoid clashing of names
|
||||||
|
LOG.debug("Going to upload the files");
|
||||||
|
listTempDirs = recursiveUploadFileset(monitoringActionsOnServer, mongoService, profileID, theProject,
|
||||||
|
tree_Node, null, listTempDirs);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error on uploading files: ", e);
|
||||||
|
throw new Exception("Error occurred on uploading files, try again or contact the support. Error: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
ProjectsCaller client = GeoportalClientCaller.projects();
|
||||||
|
SessionUtil.getCurrentContext(getThreadLocalRequest(), true);
|
||||||
|
LOG.info("stepsOnPostCreation are {}", stepsOnPostCreation);
|
||||||
|
for (String stepID : stepsOnPostCreation) {
|
||||||
|
LOG.info("calling step OnPostCreation are {}", stepID);
|
||||||
|
|
||||||
|
// 4. Action to Monitoring
|
||||||
|
MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS, "Performing step: " + stepID);
|
||||||
|
action = monitoringActionsOnServer.pushAction(action);
|
||||||
|
|
||||||
|
theProject = client.performStep(theProject.getProfileID(), theProject.getId(), stepID, null, null);
|
||||||
|
|
||||||
|
// 4. Action completed
|
||||||
|
action.setMsg("Performed step: " + stepID);
|
||||||
|
action.setStatus(STATUS.DONE);
|
||||||
|
monitoringActionsOnServer.overrideAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Error occurred on performing steps " + stepsOnPostCreation + " on the project: "
|
||||||
|
+ theProject.getId() + ". Error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
LifecycleInformation lifecycleInfo = theProject.getLifecycleInformation();
|
||||||
|
LifecycleInformationDV liDV = ConvertToDataValueObjectModel.toLifecycleInformationDV(lifecycleInfo);
|
||||||
|
|
||||||
|
monitoringActionsOnServer.setCommitReport(new CommitReport(theProject.getId(),
|
||||||
|
theProject.getProfileID(), theProject.getTheDocument().toJson(), liDV));
|
||||||
|
monitoringActionsOnServer.setMonitoringTerminated(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Error occurred on loading LifecycleInformation for the project: "
|
||||||
|
+ theProject.getId() + ". Error: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new Exception("Error occurred on performing steps " + stepsOnPostCreation + " on the project: "
|
// general catch
|
||||||
+ theProject.getId() + ". Error: " + e.getMessage());
|
LOG.error("General Error: ", e.getMessage());
|
||||||
}
|
monitoringActionsOnServer.setException(e);
|
||||||
|
monitoringActionsOnServer.setMonitoringTerminated(true);
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
LifecycleInformation lifecycleInfo = theProject.getLifecycleInformation();
|
|
||||||
LifecycleInformationDV liDV = ConvertToDataValueObjectModel.toLifecycleInformationDV(lifecycleInfo);
|
|
||||||
|
|
||||||
return new CommitReport(theProject.getId(), theProject.getProfileID(), theProject.getTheDocument().toJson(),
|
|
||||||
liDV);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Error occurred on loading LifecycleInformation for the project: " + theProject.getId()
|
|
||||||
+ ". Error: " + e.getMessage());
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
LOG.debug("List listTempDirs is: " + listTempDirs);
|
LOG.debug("List listTempDirs is: " + listTempDirs);
|
||||||
|
@ -240,12 +295,52 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
long endDiffMillis = System.currentTimeMillis() - startTime;
|
long endDiffMillis = System.currentTimeMillis() - startTime;
|
||||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(endDiffMillis);
|
long minutes = TimeUnit.MILLISECONDS.toMinutes(endDiffMillis);
|
||||||
LOG.info("Procedure terminated in ms: " + endDiffMillis + ", minutes: " + minutes);
|
LOG.info("Procedure terminated in ms: " + endDiffMillis + ", minutes: " + minutes);
|
||||||
|
// monitorActions.destroyMonitor();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// silent
|
// silent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MonitoringActionsOnClient getSavingProjectMonitorStatus(String monitorUUID,
|
||||||
|
boolean isMonitoringTerminatedClientConsumed) throws Exception {
|
||||||
|
LOG.info("getSavingProjectMonitorStatus called for: " + monitorUUID);
|
||||||
|
|
||||||
|
MonitoringActionsOnServer mas = SessionUtil.getMonitorStatus(getThreadLocalRequest(), monitorUUID);
|
||||||
|
|
||||||
|
// destroying the monitor
|
||||||
|
if (isMonitoringTerminatedClientConsumed) {
|
||||||
|
LOG.info("monitor for " + monitorUUID + " consumed on client side, destroying it");
|
||||||
|
mas.destroyMonitor();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// converting the monitor to the client version
|
||||||
|
MonitoringActionsOnClient macU = clientMonitor.apply(mas);
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("returning monitor on client: " + macU);
|
||||||
|
}
|
||||||
|
LOG.info("returning monitor for " + monitorUUID);
|
||||||
|
return macU;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Function<MonitoringActionsOnServer, MonitoringActionsOnClient> clientMonitor = new Function<MonitoringActionsOnServer, MonitoringActionsOnClient>() {
|
||||||
|
|
||||||
|
public MonitoringActionsOnClient apply(MonitoringActionsOnServer ms) {
|
||||||
|
MonitoringActionsOnClient mac = new MonitoringActionsOnClient();
|
||||||
|
mac.setCommitReport(ms.getCommitReport());
|
||||||
|
mac.setMonitor(ms.getMonitor());
|
||||||
|
mac.setException(ms.getException());
|
||||||
|
mac.setMonitorUUID(ms.getMonitorUUID());
|
||||||
|
mac.setMonitoringTerminatedOnServer(ms.isMonitoringTerminatedOnServer());
|
||||||
|
|
||||||
|
return mac;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update geportal data form.
|
* Update geportal data form.
|
||||||
*
|
*
|
||||||
|
@ -398,7 +493,7 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Project with id " + currentProject.getId() + " updated correclty");
|
LOG.info("Project with id " + currentProject.getId() + " updated correctly");
|
||||||
ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true);
|
ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true);
|
||||||
// Reading again the project to be sure
|
// Reading again the project to be sure
|
||||||
updatedProject = client.getProjectByID(profileID, projectID);
|
updatedProject = client.getProjectByID(profileID, projectID);
|
||||||
|
@ -430,6 +525,7 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
/**
|
/**
|
||||||
* Recursive upload fileset.
|
* Recursive upload fileset.
|
||||||
*
|
*
|
||||||
|
* @param monitorActions the monitor actions
|
||||||
* @param mongoService the mongo service
|
* @param mongoService the mongo service
|
||||||
* @param profileID the profile ID
|
* @param profileID the profile ID
|
||||||
* @param theProject the the project
|
* @param theProject the the project
|
||||||
|
@ -439,7 +535,8 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
* @return the list
|
* @return the list
|
||||||
* @throws Exception the exception
|
* @throws Exception the exception
|
||||||
*/
|
*/
|
||||||
public List<File> recursiveUploadFileset(MongoServiceUtil mongoService, String profileID, Project theProject,
|
public List<File> recursiveUploadFileset(final MonitoringActionsOnServer monitorActions,
|
||||||
|
MongoServiceUtil mongoService, String profileID, Project theProject,
|
||||||
Tree_Node<GeoNaFormDataObject> tree_Node, Map<String, Integer> sectionJSONPathIndexer, List<File> tempDirs)
|
Tree_Node<GeoNaFormDataObject> tree_Node, Map<String, Integer> sectionJSONPathIndexer, List<File> tempDirs)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
LOG.debug("recursiveUploadFileset called [tree_Node: " + tree_Node + "], [jsonPathIndexer: "
|
LOG.debug("recursiveUploadFileset called [tree_Node: " + tree_Node + "], [jsonPathIndexer: "
|
||||||
|
@ -493,6 +590,12 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
Map<String, FileSetDataObject> collectFilesetPerFieldDef = new HashMap<String, FileSetDataObject>();
|
Map<String, FileSetDataObject> collectFilesetPerFieldDef = new HashMap<String, FileSetDataObject>();
|
||||||
List<FileUploaded> files = gdb.getFilesUploaded();
|
List<FileUploaded> files = gdb.getFilesUploaded();
|
||||||
if (files.size() > 0) {
|
if (files.size() > 0) {
|
||||||
|
// List<String> fileNames = files.stream().map(fl ->
|
||||||
|
// fl.getFileName()).collect(Collectors.toList());
|
||||||
|
// 1..N Monitoring Copying files
|
||||||
|
// MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
// "Copying file/s: " + fileNames);
|
||||||
|
// action = monitorActions.pushAction(action);
|
||||||
// Iterating on the files upload for the section
|
// Iterating on the files upload for the section
|
||||||
for (int i = 0; i < files.size(); i++) {
|
for (int i = 0; i < files.size(); i++) {
|
||||||
FileUploaded file = files.get(i);
|
FileUploaded file = files.get(i);
|
||||||
|
@ -500,6 +603,7 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
String formFieldName = file.getFilePath().getFormFieldLabel();
|
String formFieldName = file.getFilePath().getFormFieldLabel();
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
"Uploading file: " + file.getFileName() + ", from formFieldName: " + formFieldName);
|
"Uploading file: " + file.getFileName() + ", from formFieldName: " + formFieldName);
|
||||||
|
|
||||||
FilePathDV filePath = retrieveFilePathForGcubeProfileFieldName(formFieldName, profile);
|
FilePathDV filePath = retrieveFilePathForGcubeProfileFieldName(formFieldName, profile);
|
||||||
LOG.info("Found {} for the form fieldName {}", filePath, formFieldName);
|
LOG.info("Found {} for the form fieldName {}", filePath, formFieldName);
|
||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
|
@ -542,6 +646,11 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1..N Monitoring Fileset copied action completed
|
||||||
|
// action.setMsg("File/s " + fileNames + " copied correctly");
|
||||||
|
// action.setStatus(STATUS.DONE);
|
||||||
|
// monitorActions.overrideAction(action);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Cluster of fileset per fieldDefinition is: " + collectFilesetPerFieldDef);
|
LOG.info("Cluster of fileset per fieldDefinition is: " + collectFilesetPerFieldDef);
|
||||||
|
@ -553,31 +662,47 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
File[] fileset = uploadedFileset.getFileset();
|
File[] fileset = uploadedFileset.getFileset();
|
||||||
FilePathDV filePath = uploadedFileset.getFilePathDV();
|
FilePathDV filePath = uploadedFileset.getFilePathDV();
|
||||||
|
|
||||||
|
// Getting fileNames for the monitoring
|
||||||
|
List<String> fileNames = new ArrayList<String>();
|
||||||
|
if (fileset != null)
|
||||||
|
fileNames = Arrays.asList(fileset).stream().map(f -> f.getName()).collect(Collectors.toList());
|
||||||
|
|
||||||
Access access;
|
Access access;
|
||||||
// If the maxOccurs is not 1
|
// If the maxOccurs is not 1
|
||||||
if (profile.getMaxOccurs() == 0 || profile.getMaxOccurs() > 1) {
|
if (profile.getMaxOccurs() == 0 || profile.getMaxOccurs() > 1) {
|
||||||
LOG.info("The gCube Profile with the section " + sectionJSONPath
|
LOG.info("The gCube Profile with the section " + sectionJSONPath
|
||||||
+ " has maxOccurs > 1 need to manage it as array, going to add the array index");
|
+ " has maxOccurs > 1 need to manage it as array, going to add the array index");
|
||||||
String arraySectionJSONPAth = String.format("%s[%d]", sectionJSONPath, jpcV);
|
String arraySectionJSONPAth = String.format("%s[%d]", sectionJSONPath, jpcV);
|
||||||
LOG.debug("registering the fileset in the array section: " + sectionJSONPath);
|
LOG.debug("registering the fileset in the array section: " + arraySectionJSONPAth);
|
||||||
|
|
||||||
access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument,
|
access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument,
|
||||||
arraySectionJSONPAth);
|
arraySectionJSONPAth);
|
||||||
mongoService.registerFileSet(profileID, theProject, arraySectionJSONPAth,
|
|
||||||
filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset);
|
monitoredRegisteredFileset(mongoService, monitorActions, profileID, theProject,
|
||||||
|
arraySectionJSONPAth, filePath.getFieldName(), filePath.getFieldDefinition(), access,
|
||||||
|
fileset);
|
||||||
|
|
||||||
|
// mongoService.registerFileSet(profileID, theProject, arraySectionJSONPAth,
|
||||||
|
// filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG.info("The gCube Profile with the section " + sectionJSONPath + " has maxOccurs = 1");
|
LOG.info("The gCube Profile with the section " + sectionJSONPath + " has maxOccurs = 1");
|
||||||
LOG.debug("registering the fileset in the section: " + sectionJSONPath);
|
LOG.debug("registering the fileset in the section: " + sectionJSONPath);
|
||||||
access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument,
|
access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument,
|
||||||
sectionJSONPath);
|
sectionJSONPath);
|
||||||
mongoService.registerFileSet(profileID, theProject, sectionJSONPath, filePath.getFieldName(),
|
|
||||||
filePath.getFieldDefinition(), access, fileset);
|
monitoredRegisteredFileset(mongoService, monitorActions, profileID, theProject, sectionJSONPath,
|
||||||
|
filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset);
|
||||||
|
|
||||||
|
// mongoService.registerFileSet(profileID, theProject, sectionJSONPath, filePath.getFieldName(),
|
||||||
|
// filePath.getFieldDefinition(), access, fileset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempDirs = recursiveUploadFileset(mongoService, profileID, theProject, treeNodeChild_GNA_DO,
|
tempDirs = recursiveUploadFileset(monitorActions, mongoService, profileID, theProject,
|
||||||
sectionJSONPathIndexer, tempDirs);
|
treeNodeChild_GNA_DO, sectionJSONPathIndexer, tempDirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -586,6 +711,44 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void monitoredRegisteredFileset(final MongoServiceUtil mongoService,
|
||||||
|
final MonitoringActionsOnServer monitorActions, String profileID, Project theProject,
|
||||||
|
String sectionJSONPath, String fieldName, String fieldDefinition, Access access, File... fileset) {
|
||||||
|
|
||||||
|
// Getting fileNames for the monitoring
|
||||||
|
List<String> fileNames = new ArrayList<String>();
|
||||||
|
if (fileset != null)
|
||||||
|
fileNames = Arrays.asList(fileset).stream().map(f -> f.getName()).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 1..N Monitoring Registering Fileset
|
||||||
|
MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
"Registering and indexing the fileset: " + fileNames);
|
||||||
|
monitorActions.pushAction(action);
|
||||||
|
|
||||||
|
boolean error = false;
|
||||||
|
try {
|
||||||
|
|
||||||
|
mongoService.registerFileSet(profileID, theProject, sectionJSONPath, fieldName, fieldDefinition, access,
|
||||||
|
fileset);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
error = true;
|
||||||
|
LOG.error("Error on registering fileset: ", e);
|
||||||
|
// 1..N Monitoring Fileset not registered
|
||||||
|
action.setMsg("Fileset " + fileNames + " not registered. Error: "+e.getMessage());
|
||||||
|
action.setStatus(STATUS.FAILED);
|
||||||
|
monitorActions.overrideAction(action);
|
||||||
|
} finally {
|
||||||
|
if (!error) {
|
||||||
|
// 1..N Monitoring Fileset registered correctly completed
|
||||||
|
action.setMsg("Fileset " + fileNames + " registered correctly");
|
||||||
|
action.setStatus(STATUS.DONE);
|
||||||
|
monitorActions.overrideAction(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect files.
|
* Collect files.
|
||||||
*
|
*
|
||||||
|
@ -1030,15 +1193,18 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
|
|
||||||
client.deleteProject(profileID, projectID, true);
|
client.deleteProject(profileID, projectID, true);
|
||||||
|
|
||||||
|
// To be sure project deleted
|
||||||
|
Project deletedP = null;
|
||||||
try {
|
try {
|
||||||
Project deletedP = client.getProjectByID(profileID, projectID);
|
deletedP = client.getProjectByID(profileID, projectID);
|
||||||
if (deletedP != null) {
|
|
||||||
String error = "The project with id " + projectID + " still exists";
|
|
||||||
LOG.error(error + ". Sending exception..");
|
|
||||||
throw new Exception(error);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw e;
|
// silent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deletedP != null) {
|
||||||
|
String error = "The project with id " + projectID + " still exists";
|
||||||
|
LOG.error(error + ". Sending exception..");
|
||||||
|
throw new Exception(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating count of Documents in session per profileID
|
// Updating count of Documents in session per profileID
|
||||||
|
@ -1075,7 +1241,7 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen
|
||||||
Document updatedDocument = Serialization.read(jsonUpdate, Document.class);
|
Document updatedDocument = Serialization.read(jsonUpdate, Document.class);
|
||||||
LOG.info("updatedDocument is {}", updatedDocument);
|
LOG.info("updatedDocument is {}", updatedDocument);
|
||||||
Project project = client.updateProject(profileID, projectID, updatedDocument);
|
Project project = client.updateProject(profileID, projectID, updatedDocument);
|
||||||
LOG.info("Project with id " + project.getId() + " updated correclty");
|
LOG.info("Project with id " + project.getId() + " updated correctly");
|
||||||
ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true);
|
ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true);
|
||||||
return ConvertToDataValueObjectModel.toProjectDV(project, projectBuilder);
|
return ConvertToDataValueObjectModel.toProjectDV(project, projectBuilder);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.server;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction;
|
||||||
|
|
||||||
|
public class MonitoringActionsOnServer implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -2370892426311458184L;
|
||||||
|
|
||||||
|
private LinkedHashMap<Integer, MonitoringAction> monitor = new LinkedHashMap<Integer, MonitoringAction>();
|
||||||
|
|
||||||
|
private Exception exception;
|
||||||
|
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
private String monitorUUID;
|
||||||
|
|
||||||
|
private CommitReport commitReport;
|
||||||
|
|
||||||
|
private boolean monitoringTerminatedOnServer;
|
||||||
|
|
||||||
|
private boolean monitoringTerminatedClientConsumed;
|
||||||
|
|
||||||
|
public MonitoringActionsOnServer(HttpServletRequest httpServletRequest, String monitorUUID) {
|
||||||
|
this.request = httpServletRequest;
|
||||||
|
this.monitorUUID = monitorUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push action.
|
||||||
|
*
|
||||||
|
* @param action the action
|
||||||
|
* @return the action Id
|
||||||
|
*/
|
||||||
|
public synchronized MonitoringAction pushAction(MonitoringAction action) {
|
||||||
|
final int current = monitor.size();
|
||||||
|
int actionId = current + 1;
|
||||||
|
action.setActionId(actionId);
|
||||||
|
monitor.put(actionId, action);
|
||||||
|
updateMonitorInSession();
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void overrideAction(MonitoringAction action) {
|
||||||
|
monitor.put(action.getActionId(), action);
|
||||||
|
updateMonitorInSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonitoringAction getAction(Integer index) {
|
||||||
|
if (index == null || index < 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return monitor.get(index);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<Integer, MonitoringAction> getMonitor() {
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMonitorInSession() {
|
||||||
|
SessionUtil.setMonitorStatus(request, monitorUUID, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonitoringTerminated(boolean bool) {
|
||||||
|
this.monitoringTerminatedOnServer = bool;
|
||||||
|
updateMonitorInSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMonitoringTerminatedOnServer() {
|
||||||
|
return monitoringTerminatedOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyMonitor() {
|
||||||
|
SessionUtil.removeMonitorStatus(request, monitorUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception getException() {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setException(Exception exception) {
|
||||||
|
this.exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommitReport(CommitReport commitReport) {
|
||||||
|
this.commitReport = commitReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommitReport getCommitReport() {
|
||||||
|
return commitReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMonitorUUID() {
|
||||||
|
return monitorUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -41,7 +41,8 @@ public class SessionUtil {
|
||||||
|
|
||||||
private static final String GNA_DATAENTRY_CONFIG_PROFILE = "GNA_DATAENTRY_CONFIG_PROFILE";
|
private static final String GNA_DATAENTRY_CONFIG_PROFILE = "GNA_DATAENTRY_CONFIG_PROFILE";
|
||||||
private static final String LATEST_RESULT_SET_SORTED = "LATEST_RESULT_SET_SORTED";
|
private static final String LATEST_RESULT_SET_SORTED = "LATEST_RESULT_SET_SORTED";
|
||||||
//private static final String GEONA_DATAVIEWER_PROFILE = "GEONA_DATAVIEWER_PROFILE";
|
// private static final String GEONA_DATAVIEWER_PROFILE =
|
||||||
|
// "GEONA_DATAVIEWER_PROFILE";
|
||||||
private static final String LIST_OF_CONCESSIONI = "LIST_OF_CONCESSIONI";
|
private static final String LIST_OF_CONCESSIONI = "LIST_OF_CONCESSIONI";
|
||||||
|
|
||||||
private static final String LIST_OF_RELATIONSHIP_DEFINITION = "LIST_OF_RELATIONSHIP_DEFINITION";
|
private static final String LIST_OF_RELATIONSHIP_DEFINITION = "LIST_OF_RELATIONSHIP_DEFINITION";
|
||||||
|
@ -325,7 +326,7 @@ public class SessionUtil {
|
||||||
HttpSession session = threadLocalRequest.getSession();
|
HttpSession session = threadLocalRequest.getSession();
|
||||||
session.setAttribute(LIST_OF_RELATIONSHIP_DEFINITION + profileID, listRelationshipNames);
|
session.setAttribute(LIST_OF_RELATIONSHIP_DEFINITION + profileID, listRelationshipNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the JSON timeline template.
|
* Gets the JSON timeline template.
|
||||||
*
|
*
|
||||||
|
@ -351,5 +352,32 @@ public class SessionUtil {
|
||||||
session.setAttribute(TIMELINE_JSON_TEMPLATE + profileID, jsonTimelineTemplate);
|
session.setAttribute(TIMELINE_JSON_TEMPLATE + profileID, jsonTimelineTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setMonitorStatus(HttpServletRequest httpServletRequest, String uuidAsString,
|
||||||
|
MonitoringActionsOnServer monitorActions) {
|
||||||
|
HttpSession session = httpServletRequest.getSession();
|
||||||
|
String monitorID = getUniqueMonitorID(uuidAsString);
|
||||||
|
session.setAttribute(monitorID, monitorActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeMonitorStatus(HttpServletRequest httpServletRequest, String uuidAsString) {
|
||||||
|
HttpSession session = httpServletRequest.getSession();
|
||||||
|
String monitorID = getUniqueMonitorID(uuidAsString);
|
||||||
|
session.removeAttribute(monitorID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MonitoringActionsOnServer getMonitorStatus(HttpServletRequest httpServletRequest, String uuidAsString) {
|
||||||
|
HttpSession session = httpServletRequest.getSession();
|
||||||
|
String monitorID = getUniqueMonitorID(uuidAsString);
|
||||||
|
try {
|
||||||
|
return (MonitoringActionsOnServer) session.getAttribute(monitorID);
|
||||||
|
}catch (Exception e) {
|
||||||
|
LOG.warn("No monitor in session for id: "+monitorID);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getUniqueMonitorID(String uuid) {
|
||||||
|
return uuid + "_MONITOR";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.server.test;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.server.MonitoringActionsOnServer;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction;
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.monitoring.MonitoringAction.STATUS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class MockData.
|
||||||
|
*
|
||||||
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||||
|
*
|
||||||
|
* Oct 14, 2024
|
||||||
|
*/
|
||||||
|
public class MockData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock monitor.
|
||||||
|
*
|
||||||
|
* @param uuidAsString the uuid as string
|
||||||
|
* @param request the request
|
||||||
|
* @throws InterruptedException the interrupted exception
|
||||||
|
*/
|
||||||
|
public static final void mockMonitor(String uuidAsString, HttpServletRequest request) throws InterruptedException {
|
||||||
|
|
||||||
|
final MonitoringActionsOnServer monitoringActionsOnServer = new MonitoringActionsOnServer(request,
|
||||||
|
uuidAsString);
|
||||||
|
|
||||||
|
// 1. Action to Monitoring
|
||||||
|
MonitoringAction action = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
"Converting prject metadata to Geoportal data model");
|
||||||
|
action = monitoringActionsOnServer.pushAction(action);
|
||||||
|
|
||||||
|
// 1. Action completed
|
||||||
|
action.setMsg("Converted prject metadata to Geoportal data model");
|
||||||
|
action.setStatus(STATUS.DONE);
|
||||||
|
monitoringActionsOnServer.overrideAction(action);
|
||||||
|
|
||||||
|
// 2. Action to Monitoring
|
||||||
|
MonitoringAction action2 = new MonitoringAction(STATUS.IN_PROGESS,
|
||||||
|
"Creating project on Geoportal Storage service");
|
||||||
|
action2 = monitoringActionsOnServer.pushAction(action2);
|
||||||
|
|
||||||
|
Thread.sleep(5000);
|
||||||
|
|
||||||
|
// 2. Action completed
|
||||||
|
action2.setMsg("Created project on Geoportal Storage service");
|
||||||
|
action2.setStatus(STATUS.DONE);
|
||||||
|
monitoringActionsOnServer.overrideAction(action2);
|
||||||
|
|
||||||
|
// 3. Action to Monitoring
|
||||||
|
MonitoringAction action3 = new MonitoringAction(STATUS.IN_PENDING, "Going to register the file/s...");
|
||||||
|
action3 = monitoringActionsOnServer.pushAction(action3);
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
|
||||||
|
String fileName = "File " + i;
|
||||||
|
// 1..N Monitoring Uploading Fileset
|
||||||
|
MonitoringAction actionI = new MonitoringAction(STATUS.IN_PROGESS, "Registering the fileset: " + fileName);
|
||||||
|
actionI = monitoringActionsOnServer.pushAction(actionI);
|
||||||
|
|
||||||
|
Thread.sleep(5000);
|
||||||
|
// 1..N Monitoring Fileset uploaded action completed
|
||||||
|
actionI.setMsg("Fileset " + fileName + " registered correclty");
|
||||||
|
actionI.setStatus(STATUS.DONE);
|
||||||
|
monitoringActionsOnServer.overrideAction(actionI);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
monitoringActionsOnServer.setMonitoringTerminated(true);
|
||||||
|
Thread.sleep(5000);
|
||||||
|
|
||||||
|
CommitReport commitReport = new CommitReport("Mock projectId", "Mock profileId", null, null);
|
||||||
|
monitoringActionsOnServer.setCommitReport(commitReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.shared.monitoring;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class MonitoringAction implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7129157692965636149L;
|
||||||
|
private Integer actionId;
|
||||||
|
private STATUS status;
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
public static enum STATUS {
|
||||||
|
IN_PENDING("Pending", "Operation in Pending"),
|
||||||
|
IN_PROGESS("Progress", "Operation in Progress"),
|
||||||
|
FAILED("Failed", "Operation Failed"),
|
||||||
|
DONE("Done", "Operation Done");
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String label;
|
||||||
|
|
||||||
|
STATUS(String id, String label) {
|
||||||
|
this.id = id;
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonitoringAction() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonitoringAction(STATUS status, String msg) {
|
||||||
|
this.status = status;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonitoringAction(Integer actionId, STATUS status, String msg) {
|
||||||
|
this(status, msg);
|
||||||
|
this.actionId = actionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public STATUS getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(STATUS status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getActionId() {
|
||||||
|
return actionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActionId(Integer actionId) {
|
||||||
|
this.actionId = actionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("MonitoringAction [actionId=");
|
||||||
|
builder.append(actionId);
|
||||||
|
builder.append(", status=");
|
||||||
|
builder.append(status);
|
||||||
|
builder.append(", msg=");
|
||||||
|
builder.append(msg);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.gcube.portlets.user.geoportaldataentry.shared.monitoring;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport;
|
||||||
|
|
||||||
|
public class MonitoringActionsOnClient implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -8517260295153833253L;
|
||||||
|
|
||||||
|
private LinkedHashMap<Integer, MonitoringAction> monitor = new LinkedHashMap<Integer, MonitoringAction>();
|
||||||
|
|
||||||
|
private Exception exception;
|
||||||
|
|
||||||
|
private String monitorUUID;
|
||||||
|
|
||||||
|
private CommitReport commitReport;
|
||||||
|
|
||||||
|
private boolean monitoringTerminatedOnServer;
|
||||||
|
|
||||||
|
public MonitoringActionsOnClient() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<Integer, MonitoringAction> getMonitor() {
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception getException() {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMonitorUUID() {
|
||||||
|
return monitorUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommitReport getCommitReport() {
|
||||||
|
return commitReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMonitoringTerminatedOnServer() {
|
||||||
|
return monitoringTerminatedOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonitor(LinkedHashMap<Integer, MonitoringAction> monitor) {
|
||||||
|
this.monitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setException(Exception exception) {
|
||||||
|
this.exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonitorUUID(String monitorUUID) {
|
||||||
|
this.monitorUUID = monitorUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommitReport(CommitReport commitReport) {
|
||||||
|
this.commitReport = commitReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonitoringTerminatedOnServer(boolean monitoringTerminatedOnServer) {
|
||||||
|
this.monitoringTerminatedOnServer = monitoringTerminatedOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("MonitoringActionsOnClient [monitor=");
|
||||||
|
builder.append(monitor);
|
||||||
|
builder.append(", exception=");
|
||||||
|
builder.append(exception);
|
||||||
|
builder.append(", monitorUUID=");
|
||||||
|
builder.append(monitorUUID);
|
||||||
|
builder.append(", commitReport=");
|
||||||
|
builder.append(commitReport);
|
||||||
|
builder.append(", monitoringTerminatedOnServer=");
|
||||||
|
builder.append(monitoringTerminatedOnServer);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue