diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/SchedulingController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/SchedulingController.java index 8c648b4a055ff7fa1101490bf967c37a6a7a4350..805e21498361e3c722a7cf592329fef2679b71ca 100755 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/SchedulingController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/SchedulingController.java @@ -129,9 +129,9 @@ public class SchedulingController extends HttpServlet { // Authorization: SUPERUSER ONLY else if(action.equals("viewAllTasks")) { - if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER)) + if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER, VipsLogicRole.ORGANIZATION_ADMINISTRATOR)) { - List<VipsLogicTask> allTasks = schedulingBean.getAllVipsLogicTasks(); + List<VipsLogicTask> allTasks = schedulingBean.getVipsLogicTasks(user); request.setAttribute("tasks", allTasks); // If this is a redirect from a controller, with a message to be passed on request.setAttribute("messageKey", request.getParameter("messageKey")); @@ -147,12 +147,16 @@ public class SchedulingController extends HttpServlet { // Authorization: SUPERUSER ONLY else if(action.equals("runTaskManuallyForm")) { - if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER)) + if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER, VipsLogicRole.ORGANIZATION_ADMINISTRATOR)) { try { Integer factoryId = Integer.valueOf(request.getParameter("factoryId")); VipsLogicTask task = VipsLogicTaskFactory.createVipsLogicTask(factoryId); + if(!user.isSuperUser()) // Some tasks need organization id set to create a sensible form for an orgAdmin + { + task.setOrganization(user.getOrganizationId()); + } request.setAttribute("vipsLogicTask", task); //request.setAttribute("testJSON", task.getConfigFormDefinition()); String language = SessionLocaleUtil.getCurrentLocale(request).getLanguage(); @@ -176,7 +180,7 @@ public class SchedulingController extends HttpServlet { // Authorization: SUPERUSER ONLY else if(action.equals("runTaskManuallyFormSubmit")) { - if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER)) + if(userBean.authorizeUser(user, VipsLogicRole.SUPERUSER, VipsLogicRole.ORGANIZATION_ADMINISTRATOR)) { try { @@ -189,6 +193,10 @@ public class SchedulingController extends HttpServlet { // Need to copy the ParameterMap (not just pass it along), as the values get lost // after the servlet disconnects itself from the task task.setConfiguration(new HashMap<>(request.getParameterMap())); + if(user.isOrganizationAdmin()) + { + task.setOrganization(user.getOrganizationId()); + } // If system scheduler is running, launch task there if(schedulingBean.getSystemScheduler().isStarted()) { diff --git a/src/main/java/no/nibio/vips/logic/controller/session/SchedulingBean.java b/src/main/java/no/nibio/vips/logic/controller/session/SchedulingBean.java index 108f4f7059bbb01c267e6e40af5b36927a1fd1ca..7fa9924f042dc7277bcc80c4ca3ff39a94a10505 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/SchedulingBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/SchedulingBean.java @@ -334,9 +334,22 @@ public class SchedulingBean { } - public List<VipsLogicTask> getAllVipsLogicTasks() + public List<VipsLogicTask> getVipsLogicTasks(VipsLogicUser user) { - return VipsLogicTaskFactory.getAllVipsLogicTasks(); + // Super User + if(user.isSuperUser()) + { + return VipsLogicTaskFactory.getAllVipsLogicTasks(); + } + // Organization admin + else if(user.isOrganizationAdmin()) + { + return VipsLogicTaskFactory.getOrganizationAdminVipsLogicTasks(); + } + else + { + return null; + } } public ManagerResource getManagerResource() diff --git a/src/main/java/no/nibio/vips/logic/scheduling/VipsLogicTaskFactory.java b/src/main/java/no/nibio/vips/logic/scheduling/VipsLogicTaskFactory.java index 580320af31b54159b198d27b6f8e47b611bf084a..f59aac6ca0a018dfdfaf2ed52805da619a8c1dd8 100755 --- a/src/main/java/no/nibio/vips/logic/scheduling/VipsLogicTaskFactory.java +++ b/src/main/java/no/nibio/vips/logic/scheduling/VipsLogicTaskFactory.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import no.nibio.vips.logic.scheduling.tasks.DeleteAllExpiredUserUuidsTask; +import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsForOrganizationTask; import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsTask; import no.nibio.vips.logic.scheduling.tasks.SendForecastEventNotificationsTask; import no.nibio.vips.logic.scheduling.tasks.UpdateForecastResultCacheTableTask; @@ -32,7 +33,7 @@ import no.nibio.vips.logic.scheduling.tasks.UpdateModelInformationTask; /** * Provides the requested VipsLogicTask - * @copyright 2013-2015 <a href="http://www.nibio.no/">NIBIO</a> + * @copyright 2013-2017 <a href="http://www.nibio.no/">NIBIO</a> * @author Tor-Einar Skog <tor-einar.skog@nibio.no> */ public class VipsLogicTaskFactory { @@ -43,10 +44,14 @@ public class VipsLogicTaskFactory { public static final int UPDATE_FORECAST_SUMMARY_TABLE_TASK = 4; public static final int DELETE_ALL_EXPIRED_UUIDS_TASK = 5; public static final int SEND_FORECAST_EVENT_NOTIFICATIONS_TASK = 6; + public static final int RUN_ALL_FORECAST_CONFIGURATIONS_FOR_ORGANIZATION_TASK = 7; - private final static int[] ALL_TASK_IDS = {1,2,3,4,5,6}; + private final static int[] ALL_TASK_IDS = {1,2,3,4,5,6,7}; + + private final static int[] ORGANIZATION_ADMIN_TASK_IDS = {7}; private static List<VipsLogicTask> allTasksList; + private static List<VipsLogicTask> organizationAdminTasksList; private static Map<String,VipsLogicTask> allTasksMap; /** @@ -77,6 +82,9 @@ public class VipsLogicTaskFactory { case SEND_FORECAST_EVENT_NOTIFICATIONS_TASK: retVal = new SendForecastEventNotificationsTask(); break; + case RUN_ALL_FORECAST_CONFIGURATIONS_FOR_ORGANIZATION_TASK: + retVal = new RunAllForecastConfigurationsForOrganizationTask(); + break; default: return null; } @@ -116,4 +124,16 @@ public class VipsLogicTaskFactory { } return allTasksMap; } + + public static List<VipsLogicTask> getOrganizationAdminVipsLogicTasks() { + if(organizationAdminTasksList == null) + { + organizationAdminTasksList = new ArrayList<>(); + for(int i:ORGANIZATION_ADMIN_TASK_IDS) + { + organizationAdminTasksList.add(createVipsLogicTask(i)); + } + } + return organizationAdminTasksList; + } } diff --git a/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunAllForecastConfigurationsForOrganizationTask.java b/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunAllForecastConfigurationsForOrganizationTask.java new file mode 100644 index 0000000000000000000000000000000000000000..239745a114a4a0ec6702d14d64fda271259d7148 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunAllForecastConfigurationsForOrganizationTask.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.scheduling.tasks; + +import it.sauronsoftware.cron4j.TaskExecutionContext; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import no.nibio.vips.i18n.I18nImpl; +import no.nibio.vips.logic.entity.ForecastConfiguration; +import no.nibio.vips.logic.entity.Organization; +import no.nibio.vips.logic.entity.PointOfInterest; +import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; +import no.nibio.vips.logic.scheduling.SchedulingUtil; +import no.nibio.vips.logic.scheduling.VipsLogicTaskFactory; +import no.nibio.vips.logic.scheduling.model.PreprocessorException; +import no.nibio.vips.logic.util.RunModelException; +import no.nibio.vips.logic.util.SessionControllerGetter; +import no.nibio.vips.logic.util.SystemTime; +import no.nibio.web.forms.FormField; + +/** + * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class RunAllForecastConfigurationsForOrganizationTask extends RunAllForecastConfigurationsTask{ + private I18nImpl i18n; + //private boolean DEBUG=true; + @Override + public void execute(TaskExecutionContext tec) throws RuntimeException { + Integer weatherStationPointOfInterestId = null; + if(this.getConfiguration() != null && this.getConfiguration().get("weatherStationPointOfInterestId") != null) + { + weatherStationPointOfInterestId = Integer.valueOf(this.getConfiguration().get("weatherStationPointOfInterestId")[0]); + } + + + tec.setCompleteness(0d); + int totalNumberofForecastConfigurations = 0; + int numberOfCompletedForecastConfigurations = 0; + StringBuilder errorMessage = new StringBuilder(); + // Get all organizations, loop, get all current forecasts, loop, run models, store results + boolean noForecastConfigurationsFound = true; + + List<ForecastConfiguration> currentForecastConfigurations = SessionControllerGetter.getForecastBean().getForecastConfigurationsValidAtTime(this.getOrganization(), SystemTime.getSystemTime()); + //System.out.println("Current forecasts for " + organization.getOrganizationName() + ":" + currentForecastConfigurations.size()); + if(currentForecastConfigurations != null && !currentForecastConfigurations.isEmpty()) + { + noForecastConfigurationsFound = false; + for(ForecastConfiguration forecastConfiguration:currentForecastConfigurations) + { + if( + weatherStationPointOfInterestId == null + || weatherStationPointOfInterestId <= 0 + || forecastConfiguration.getWeatherStationPointOfInterestId().getPointOfInterestId().equals(weatherStationPointOfInterestId)) + { + try + { + totalNumberofForecastConfigurations++; + SessionControllerGetter.getForecastBean().runForecast(forecastConfiguration); + /* + if(DEBUG && totalNumberofForecastConfigurations == 2) + { + throw new RunModelException("This is a test!!!"); + }*/ + numberOfCompletedForecastConfigurations++; + //System.out.println("All went well"); + } + catch (PreprocessorException | RunModelException ex) + { + errorMessage + .append( + SchedulingUtil.createSchedulingMessageHTML( + "Error with forecast #" + forecastConfiguration.getForecastConfigurationId(), + ex.getMessage(), + SchedulingUtil.MESSAGE_STATUS_DANGER) + ); + //System.out.println("Error caught"); + continue; + } + + } + + double completeness = (double) numberOfCompletedForecastConfigurations/totalNumberofForecastConfigurations; + tec.setCompleteness(completeness); + } + } + } + + /** + * + * @return Form definition + */ + @Override + public String getConfigFormDefinition(String language) { + StringBuilder retVal = new StringBuilder() + .append("{") + .append(" \"fields\":[") + .append(" {") + .append(" \"name\":\"factoryId\",") + .append(" \"dataType\":\"").append(FormField.DATA_TYPE_INTEGER).append("\",") + .append(" \"fieldType\":\"").append(FormField.FIELD_TYPE_HIDDEN).append("\",") + .append(" \"webValue\":[\"").append(VipsLogicTaskFactory.RUN_ALL_FORECAST_CONFIGURATIONS_TASK).append("\"]") + .append(" },") + .append(" {") + .append(" \"name\":\"weatherStationPointOfInterestId\",") + .append(" \"dataType\":\"").append(FormField.DATA_TYPE_INTEGER).append("\",") + .append(" \"fieldType\":\"").append(FormField.FIELD_TYPE_SELECT_SINGLE).append("\",") + .append(" \"nullValue\":\"-1\",") + .append(" \"required\":false,") + .append(" \"options\": ["); + + + retVal.append(" {\"value\":\"") + .append("-1") + .append("\", \"label\":\"") + .append(this.getI18nImpl().getText("pleaseSelect", language)).append(" ").append(this.getI18nImpl().getText("weatherStationPointOfInterestId", language).toLowerCase()) + .append("\",\"selected\":") + .append("false") + .append("}\n"); + List<PointOfInterestWeatherStation> stations = SessionControllerGetter.getPointOfInterestBean().getWeatherstationsForOrganization(this.getOrganization(), Boolean.TRUE); + Collections.sort(stations); + for(PointOfInterest station:stations) + { + retVal.append(" ,{\"value\":\"") + .append(station.getPointOfInterestId()) + .append("\", \"label\":\"") + .append(station.getName()) + .append("\",\"selected\":") + .append("false") + .append("}\n"); + + } + retVal .append(" ]") + .append(" }"); + + + retVal .append(" ]") + .append(" }"); + + + return retVal.toString(); + } + + private I18nImpl getI18nImpl() + { + if(this.i18n == null) + { + this.i18n = new I18nImpl("no.nibio.vips.logic.i18n.vipslogictexts"); + } + return this.i18n; + } + +} diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties index 1c7c7069e7f72b21cc294c83d0c623074fcdfaa1..fec78e1cc45650ef6d8a4e874f4228ebd75e614d 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -444,3 +444,5 @@ vipsLogicRole_7=Organism editor nameAlreadyExists=The name already exists loginCredentials=Login credentials publicForecasts=Public forecasts +task_RunAllForecastConfigurationsForOrganizationTask_name=Run all forecasts for one organization +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties index 923f55ff43f485e10381a4a13f811f5fdc6abfae..afab40a559f89d869d81b910af078aacf34e8ff9 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties @@ -444,3 +444,5 @@ vipsLogicRole_7=Organism editor nameAlreadyExists=The name already exists loginCredentials=Login credentials publicForecasts=Public forecasts +task_RunAllForecastConfigurationsForOrganizationTask_name=Run all forecasts for one organization +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties index 964b0c085f5e448ee06cad09a9118a5985594b1a..a330cc59929a2b9ddcd515a9328bcfe5aed01214 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties @@ -443,3 +443,5 @@ vipsLogicRole_7=Organism editor nameAlreadyExists=The name already exists loginCredentials=Login credentials publicForecasts=Public forecasts +task_RunAllForecastConfigurationsForOrganizationTask_name=Run all forecasts for one organization +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties index 2d8ed37a9a076335dfdc412c898ae02551bca186..b2ac6cbecf1a5403c6b952d8ef6fa52c1568a9dc 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties @@ -444,3 +444,5 @@ vipsLogicRole_7=Organismeredakt\u00f8r nameAlreadyExists=Navnet er allerede i bruk loginCredentials=Innloggingsinformasjon publicForecasts=Offentlige varsler +task_RunAllForecastConfigurationsForOrganizationTask_name=Kj\u00f8r alle varsler for en organisasjon +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties index b02140d475ae1e2e783c5a6bd00d3604b09b7d88..d037962e082078bd6c71c52b512c057cb2b67f9a 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties @@ -444,3 +444,5 @@ vipsLogicRole_7=Organism editor nameAlreadyExists=The name already exists loginCredentials=Login credentials publicForecasts=Public forecasts +task_RunAllForecastConfigurationsForOrganizationTask_name=Run all forecasts for one organization +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties index e2d6d75972352429cabab57a4bec44d01db40c03..4d64df1b298b335d428832a46dce3fe2d13e8713 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties @@ -441,3 +441,5 @@ vipsLogicRole_7=Organism editor nameAlreadyExists=The name already exists loginCredentials=Login credentials publicForecasts=Public forecasts +task_RunAllForecastConfigurationsForOrganizationTask_name=Run all forecasts for one organization +task_RunAllForecastConfigurationsForOrganizationTask_description=Test diff --git a/src/main/webapp/templates/schedulingOverview.ftl b/src/main/webapp/templates/schedulingOverview.ftl index dc3265f405c937b157cbe0b44504a71712a71531..6bb8a9797c6c9a0fc076f323cbbf4d4ee74c2415 100755 --- a/src/main/webapp/templates/schedulingOverview.ftl +++ b/src/main/webapp/templates/schedulingOverview.ftl @@ -27,7 +27,7 @@ <div id="errorMsgEl" class="alert alert-danger" <#if !formValidation?has_content> style="display:none;"</#if>> <#if formValidation?has_content>${formValidation.validationMessages?replace("\n", "<br>")}</#if> </div> - <#if user.isSuperUser()> + <#if user.isSuperUser() || user.isOrganizationAdmin() > <p><a href="/scheduling?action=viewAllTasks">${i18nBundle.viewAllTasks}</a></p> </#if> <#if messageKey?has_content>