diff --git a/WebContent/WEB-INF/spring-security.xml b/WebContent/WEB-INF/spring-security.xml index 78f3031da1..e00019cf75 100644 --- a/WebContent/WEB-INF/spring-security.xml +++ b/WebContent/WEB-INF/spring-security.xml @@ -371,6 +371,12 @@ + + + + + + diff --git a/src/com/serotonin/mango/vo/DataPointVO.java b/src/com/serotonin/mango/vo/DataPointVO.java index ab4f36991a..5aa6edef5f 100644 --- a/src/com/serotonin/mango/vo/DataPointVO.java +++ b/src/com/serotonin/mango/vo/DataPointVO.java @@ -61,7 +61,8 @@ import static org.scada_lts.utils.XidUtils.validateXid; @JsonRemoteEntity -public class DataPointVO implements Serializable, Cloneable, JsonSerializable, ChangeComparable { +public class DataPointVO implements Serializable, Cloneable, JsonSerializable, ChangeComparable, + ScadaValidation { private static final long serialVersionUID = -1; public static final String XID_PREFIX = "DP_"; @@ -656,6 +657,7 @@ public String toString() { + ", purgeStrategy=" + purgeStrategy + ", purgeValuesLimit=" + purgeValuesLimit + "]"; } + @Override public void validate(DwrResponseI18n response) { DataPointService dataPointService = new DataPointService(); diff --git a/src/com/serotonin/mango/vo/ScadaValidation.java b/src/com/serotonin/mango/vo/ScadaValidation.java new file mode 100644 index 0000000000..a945787292 --- /dev/null +++ b/src/com/serotonin/mango/vo/ScadaValidation.java @@ -0,0 +1,7 @@ +package com.serotonin.mango.vo; + +import com.serotonin.web.dwr.DwrResponseI18n; + +public interface ScadaValidation { + void validate(DwrResponseI18n response); +} diff --git a/src/com/serotonin/mango/vo/dataSource/DataSourceVO.java b/src/com/serotonin/mango/vo/dataSource/DataSourceVO.java index a7ada87db0..221d26b5ce 100644 --- a/src/com/serotonin/mango/vo/dataSource/DataSourceVO.java +++ b/src/com/serotonin/mango/vo/dataSource/DataSourceVO.java @@ -39,6 +39,7 @@ import com.serotonin.mango.util.ChangeComparable; import com.serotonin.mango.util.ExportCodes; import com.serotonin.mango.util.LocalizableJsonException; +import com.serotonin.mango.vo.ScadaValidation; import com.serotonin.mango.vo.dataSource.bacnet.BACnetIPDataSourceVO; import com.serotonin.mango.vo.dataSource.ebro.EBI25DataSourceVO; import com.serotonin.mango.vo.dataSource.galil.GalilDataSourceVO; @@ -86,7 +87,7 @@ import static org.scada_lts.utils.XidUtils.validateXid; abstract public class DataSourceVO> extends ChangeStatus implements - Serializable, Cloneable, JsonSerializable, ChangeComparable { + Serializable, Cloneable, JsonSerializable, ChangeComparable, ScadaValidation { public enum Type { EBI25(16, "dsEdit.ebi25", false) { @Override @@ -492,6 +493,7 @@ eventId, message, getAlarmLevel(eventId, defaultAlarmLevel), duplicateHandling); } + @Override public void validate(DwrResponseI18n response) { DataSourceService dataSourceService = new DataSourceService(); diff --git a/src/org/scada_lts/utils/ApiUtils.java b/src/org/scada_lts/utils/ApiUtils.java index e9492d8313..a20a8577cd 100644 --- a/src/org/scada_lts/utils/ApiUtils.java +++ b/src/org/scada_lts/utils/ApiUtils.java @@ -1,6 +1,7 @@ package org.scada_lts.utils; import com.serotonin.mango.Common; +import com.serotonin.mango.vo.ScadaValidation; import com.serotonin.mango.vo.User; import com.serotonin.mango.vo.mailingList.EmailRecipient; import com.serotonin.mango.vo.mailingList.UserEntry; @@ -12,9 +13,11 @@ import org.apache.commons.logging.LogFactory; import org.scada_lts.mango.service.SystemSettingsService; import org.scada_lts.mango.service.UserService; +import org.scada_lts.web.mvc.api.exceptions.BadRequestException; import org.scada_lts.web.mvc.api.json.JsonSettingsMisc; import org.scada_lts.web.mvc.api.user.UserInfo; +import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -145,4 +148,17 @@ public static R convertList(List list, Function, R> converter) public static R convertList(T list, Function converter) { return converter.apply(list); } + + public static void validateObject(HttpServletRequest request, ScadaValidation toUpdate) { + DwrResponseI18n responseI18n = new DwrResponseI18n(); + toUpdate.validate(responseI18n); + if(responseI18n.getHasMessages()) { + throw new BadRequestException(toMapMessages(responseI18n), + request.getRequestURI()); + } + } + + public static boolean idExists(Integer id) { + return id != null && id > 0; + } } diff --git a/src/org/scada_lts/utils/UpdateValueUtils.java b/src/org/scada_lts/utils/UpdateValueUtils.java index b267ce068e..c559e60629 100644 --- a/src/org/scada_lts/utils/UpdateValueUtils.java +++ b/src/org/scada_lts/utils/UpdateValueUtils.java @@ -3,11 +3,11 @@ import java.util.function.Consumer; import java.util.function.Predicate; -final class UpdateValueUtils { +public final class UpdateValueUtils { private UpdateValueUtils() {} - static void setIf(T value, Consumer setter, Predicate setIf) { + public static void setIf(T value, Consumer setter, Predicate setIf) { if(setIf.test(value)) setter.accept(value); } diff --git a/src/org/scada_lts/web/mvc/api/DataPointAPI.java b/src/org/scada_lts/web/mvc/api/DataPointAPI.java index f03d108df7..b027e57e1d 100644 --- a/src/org/scada_lts/web/mvc/api/DataPointAPI.java +++ b/src/org/scada_lts/web/mvc/api/DataPointAPI.java @@ -163,5 +163,25 @@ public ResponseEntity> getDataPointIdentifiersPlcByDat List response = dataPointApiService.getDataPointIdentifiersPlcByDataSourceId(request, datasourceId); return new ResponseEntity<>(response, HttpStatus.OK); } + + @PutMapping(value = "/api/datapoint/enabled") + public ResponseEntity enableDataPoint(@RequestParam(required = false) String xid, + @RequestParam(required = false) Integer id, + HttpServletRequest request) { + LOG.debug(request.getRequestURI()); + + DataPointJson response = dataPointApiService.enableDataPoint(request, xid, id, true); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @PutMapping(value = "/api/datapoint/disabled") + public ResponseEntity disableDataPoint(@RequestParam(required = false) String xid, + @RequestParam(required = false) Integer id, + HttpServletRequest request) { + LOG.debug(request.getRequestURI()); + + DataPointJson response = dataPointApiService.enableDataPoint(request, xid, id, false); + return new ResponseEntity<>(response, HttpStatus.OK); + } } diff --git a/src/org/scada_lts/web/mvc/api/DataPointApiService.java b/src/org/scada_lts/web/mvc/api/DataPointApiService.java index 2c3a596fcc..2a275ac335 100644 --- a/src/org/scada_lts/web/mvc/api/DataPointApiService.java +++ b/src/org/scada_lts/web/mvc/api/DataPointApiService.java @@ -4,7 +4,6 @@ import com.serotonin.mango.vo.DataPointVO; import com.serotonin.mango.vo.User; import com.serotonin.mango.web.dwr.EmportDwr; -import com.serotonin.web.dwr.DwrResponseI18n; import org.scada_lts.dao.model.DataPointIdentifier; import org.scada_lts.mango.service.DataPointService; import org.scada_lts.permissions.service.GetDataPointsWithAccess; @@ -17,15 +16,15 @@ import javax.servlet.http.HttpServletRequest; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import static org.scada_lts.permissions.service.GetDataPointsWithAccess.filteringByAccess; -import static org.scada_lts.utils.ApiUtils.toMapMessages; +import static org.scada_lts.utils.ApiUtils.idExists; +import static org.scada_lts.utils.ApiUtils.validateObject; import static org.scada_lts.utils.DataSourcePointApiUtils.toObject; +import static org.scada_lts.utils.UpdateValueUtils.setIf; import static org.scada_lts.utils.ValidationUtils.*; @Service @@ -82,15 +81,35 @@ public DataPointJson create(HttpServletRequest request, DataPointJson datapoint) public DataPointJson update(HttpServletRequest request, DataPointJson datapoint) { checkIfNonAdminThenUnauthorized(request); checkArgsIfEmptyThenBadRequest(request, "Data Point cannot be null.", datapoint); - getDataPointFromDatabase(request, datapoint.getXid(), datapoint.getId()); - DataPointVO fromRequest = toDataPointVO(request, datapoint); - dataSourceApiService.read(request, fromRequest.getDataSourceXid(), fromRequest.getDataSourceId()); + DataPointVO toUpdate = getDataPointFromDatabase(request, datapoint.getXid(), datapoint.getId()); + updateObjectDataPointVO(toUpdate, datapoint); + validateObject(request, toUpdate); + DataPointJson response; try { - dataPointService.updateDataPointConfiguration(fromRequest); + dataPointService.updateDataPointConfiguration(toUpdate); + response = DataSourcePointJsonFactory.getDataPointJson(toUpdate); } catch (Exception ex) { throw new InternalServerErrorException(ex, request.getRequestURI()); } - return datapoint; + return response; + } + + public DataPointJson enableDataPoint(HttpServletRequest request, String xid, Integer id, Boolean enabled) { + checkIfNonAdminThenUnauthorized(request); + checkArgsIfEmptyThenBadRequest(request, "Enabled is required.", enabled); + checkArgsIfTwoEmptyThenBadRequest(request, "Id or xid cannot be null.", id, xid); + DataPointVO toUpdate = getDataPointFromDatabase(request, xid, id); + DataPointJson response; + if(toUpdate.isEnabled() == enabled) + throw new BadRequestException("Data point already is " + (enabled ? "enabled" : "disabled"), request.getRequestURI()); + try { + toUpdate.setEnabled(enabled); + Common.ctx.getRuntimeManager().saveDataPoint(toUpdate); + response = DataSourcePointJsonFactory.getDataPointJson(toUpdate); + } catch (Exception ex) { + throw new InternalServerErrorException(ex, request.getRequestURI()); + } + return response; } @Override @@ -158,7 +177,7 @@ public DataPointVO getDataPointFromDatabase(HttpServletRequest request, String x User user = Common.getUser(request); DataPointVO response; - if(id != null) { + if(idExists(id)) { response = toObject(id, user, request, dataPointService::getDataPoint, GetDataPointsWithAccess::hasDataPointReadPermission, a -> a); } else { @@ -243,12 +262,7 @@ private static DataPointVO toDataPointVO(HttpServletRequest request, DataPointJs } catch (Exception ex) { throw new InternalServerErrorException(ex, request.getRequestURI()); } - DwrResponseI18n responseI18n = new DwrResponseI18n(); - dataPointVO.validate(responseI18n); - if(responseI18n.getHasMessages()) { - throw new BadRequestException(toMapMessages(responseI18n), - request.getRequestURI()); - } + validateObject(request, dataPointVO); return dataPointVO; } @@ -256,7 +270,7 @@ private List getDataPointsBy(HttpServletRequest request, String dat checkArgsIfTwoEmptyThenBadRequest(request, "Data Point id or xid cannot be null.", dataSourceId, dataSourceXid); List dataPoints; try { - if (dataSourceId != null) { + if (idExists(dataSourceId)) { dataPoints = dataPointService.getDataPoints(dataSourceId, Comparator.comparing(DataPointVO::getName)); } else { @@ -275,4 +289,13 @@ private List getDataPointsBy(HttpServletRequest request, String dat } return response; } + + private static void updateObjectDataPointVO(DataPointVO toUpdate, DataPointJson fromRequest) { + setIf(fromRequest.getXid(), toUpdate::setXid, a -> !StringUtils.isEmpty(a)); + setIf(fromRequest.getPointLocator(), a -> toUpdate.setPointLocator(a.parsePointLocatorData()), Objects::nonNull); + setIf(fromRequest.getDescription(), toUpdate::setDescription, a -> !StringUtils.isEmpty(a)); + setIf(fromRequest.getName(), toUpdate::setName, a -> !StringUtils.isEmpty(a)); + setIf(fromRequest.isEnabled(), toUpdate::setEnabled, Objects::nonNull); + setIf(fromRequest.isSettable(), toUpdate::setSettable, Objects::nonNull); + } } diff --git a/src/org/scada_lts/web/mvc/api/DataSourceApiService.java b/src/org/scada_lts/web/mvc/api/DataSourceApiService.java index afbfc1b3a0..e07acc3bca 100644 --- a/src/org/scada_lts/web/mvc/api/DataSourceApiService.java +++ b/src/org/scada_lts/web/mvc/api/DataSourceApiService.java @@ -3,13 +3,11 @@ import com.serotonin.mango.Common; import com.serotonin.mango.vo.User; import com.serotonin.mango.vo.dataSource.DataSourceVO; -import com.serotonin.web.dwr.DwrResponseI18n; import org.scada_lts.dao.model.DataSourceIdentifier; import org.scada_lts.mango.service.DataSourceService; import org.scada_lts.web.mvc.api.datasources.DataPointJson; import org.scada_lts.web.mvc.api.datasources.DataSourceJson; import org.scada_lts.web.mvc.api.datasources.DataSourcePointJsonFactory; -import org.scada_lts.web.mvc.api.exceptions.BadRequestException; import org.scada_lts.web.mvc.api.exceptions.InternalServerErrorException; import org.springframework.stereotype.Service; @@ -19,7 +17,8 @@ import java.util.Map; import java.util.stream.Collectors; -import static org.scada_lts.utils.ApiUtils.toMapMessages; +import static org.scada_lts.utils.ApiUtils.idExists; +import static org.scada_lts.utils.ApiUtils.validateObject; import static org.scada_lts.utils.DataSourcePointApiUtils.toObject; import static org.scada_lts.utils.ValidationUtils.*; @@ -147,7 +146,7 @@ public Map toggleDataSource(HttpServletRequest request, String x Map response = new HashMap<>(); try { boolean state; - if(id != null) { + if(idExists(id)) { state = dataSourceService.toggleDataSource(id); } else { state = dataSourceService.toggleDataSource(xid); @@ -168,7 +167,7 @@ public List enableAllPointsInDataSource(HttpServletRequest reques List response; try { - if(id != null) { + if(idExists(id)) { response = dataSourceService.enableAllDataPointsInDS(id, user) .stream().map(DataPointJson::new) .collect(Collectors.toList()); @@ -200,7 +199,7 @@ private DataSourceVO getDataSourceFromDatabase(HttpServletRequest request, St checkArgsIfTwoEmptyThenBadRequest(request, "Id or xid cannot be null.", id, xid); User user = Common.getUser(request); DataSourceVO response; - if(id != null) { + if(idExists(id)) { response = toObject(id, user, request, dataSourceService::getDataSource, dataSourceService::hasDataSourceReadPermission, a -> a); @@ -213,19 +212,13 @@ private DataSourceVO getDataSourceFromDatabase(HttpServletRequest request, St } private static DataSourceVO toDataSourceVO(HttpServletRequest request, DataSourceJson dataSource) { - DataSourceVO vo; + DataSourceVO dataSourceVO; try { - vo = dataSource.createDataSourceVO(); + dataSourceVO = dataSource.createDataSourceVO(); } catch (Exception ex) { throw new InternalServerErrorException(ex, request.getRequestURI()); } - - DwrResponseI18n responseI18n = new DwrResponseI18n(); - vo.validate(responseI18n); - if(responseI18n.getHasMessages()) { - throw new BadRequestException(toMapMessages(responseI18n), - request.getRequestURI()); - } - return vo; + validateObject(request, dataSourceVO); + return dataSourceVO; } } diff --git a/src/org/scada_lts/web/mvc/api/datasources/DataPointJson.java b/src/org/scada_lts/web/mvc/api/datasources/DataPointJson.java index e1ec15c1c4..88328b3b03 100644 --- a/src/org/scada_lts/web/mvc/api/datasources/DataPointJson.java +++ b/src/org/scada_lts/web/mvc/api/datasources/DataPointJson.java @@ -1,17 +1,16 @@ package org.scada_lts.web.mvc.api.datasources; import com.serotonin.mango.vo.DataPointVO; -import com.serotonin.mango.vo.dataSource.PointLocatorVO; import java.util.ArrayList; public class DataPointJson { - private int id; + private Integer id; private String xid; private String name; private String description; - private boolean enabled; + private Boolean enabled; private int dataSourceTypeId; private int dataSourceId; private String deviceName; @@ -19,7 +18,7 @@ public class DataPointJson { private String datasourceName; private String dataSourceXid; private int typeId; - private boolean settable; + private Boolean settable; public DataPointJson() {} @@ -41,7 +40,7 @@ public DataPointJson(DataPointVO dpVO) { public DataPointVO createDataPointVO() { DataPointVO dpVO = new DataPointVO(); - dpVO.setId(this.id); + dpVO.setId(this.getId() != null ? this.id : 0); dpVO.setXid(this.xid); dpVO.setName(this.name); dpVO.setDescription(this.description); @@ -49,7 +48,7 @@ public DataPointVO createDataPointVO() { dpVO.setDataSourceTypeId(this.dataSourceTypeId); dpVO.setDataSourceId(this.dataSourceId); dpVO.setDeviceName(this.deviceName); - dpVO.setPointLocator((PointLocatorVO) this.pointLocator.parsePointLocatorData()); + dpVO.setPointLocator(this.pointLocator.parsePointLocatorData()); dpVO.setEventDetectors(new ArrayList<>()); dpVO.setDataSourceName(this.datasourceName); dpVO.setDataSourceXid(this.dataSourceXid); @@ -57,11 +56,11 @@ public DataPointVO createDataPointVO() { return dpVO; } - public int getId() { + public Integer getId() { return id; } - public void setId(int id) { + public void setId(Integer id) { this.id = id; } @@ -89,11 +88,11 @@ public void setDescription(String description) { this.description = description; } - public boolean isEnabled() { + public Boolean isEnabled() { return enabled; } - public void setEnabled(boolean enabled) { + public void setEnabled(Boolean enabled) { this.enabled = enabled; } @@ -145,11 +144,11 @@ public void setTypeId(int typeId) { this.typeId = typeId; } - public boolean isSettable() { + public Boolean isSettable() { return settable; } - public void setSettable(boolean settable) { + public void setSettable(Boolean settable) { this.settable = settable; } diff --git a/src/org/scada_lts/web/mvc/api/datasources/DataPointLocatorJson.java b/src/org/scada_lts/web/mvc/api/datasources/DataPointLocatorJson.java index 425f94c1c8..cd1ddf1e0a 100644 --- a/src/org/scada_lts/web/mvc/api/datasources/DataPointLocatorJson.java +++ b/src/org/scada_lts/web/mvc/api/datasources/DataPointLocatorJson.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.serotonin.json.JsonRemoteProperty; import com.serotonin.mango.vo.dataSource.PointLocatorVO; import org.scada_lts.web.mvc.api.datasources.meta.MetaPointLocatorJson; import org.scada_lts.web.mvc.api.datasources.modbusip.ModbusIpPointLocatorJson; @@ -21,8 +22,10 @@ }) public class DataPointLocatorJson { + @JsonRemoteProperty private int dataTypeId; - private boolean settable; + @JsonRemoteProperty + private Boolean settable; public DataPointLocatorJson() {} @@ -32,7 +35,7 @@ public DataPointLocatorJson(PointLocatorVO pointLocatorVO) { } public PointLocatorVO parsePointLocatorData() { - throw new UnsupportedOperationException("Method not overwritten"); + throw new UnsupportedOperationException("Unsupported type"); } public int getDataTypeId() { @@ -43,11 +46,11 @@ public void setDataTypeId(int dataTypeId) { this.dataTypeId = dataTypeId; } - public boolean isSettable() { + public Boolean isSettable() { return settable; } - public void setSettable(boolean settable) { + public void setSettable(Boolean settable) { this.settable = settable; } diff --git a/src/org/scada_lts/web/mvc/api/datasources/meta/MetaPointLocatorJson.java b/src/org/scada_lts/web/mvc/api/datasources/meta/MetaPointLocatorJson.java index 7ab4d62c4e..3b9185ab2a 100644 --- a/src/org/scada_lts/web/mvc/api/datasources/meta/MetaPointLocatorJson.java +++ b/src/org/scada_lts/web/mvc/api/datasources/meta/MetaPointLocatorJson.java @@ -15,8 +15,6 @@ public class MetaPointLocatorJson extends DataPointLocatorJson { private List context = new ArrayList<>(); @JsonRemoteProperty private String script; - @JsonRemoteProperty - private boolean settable; private UpdateEventType updateEvent = UpdateEventType.CONTEXT_CHANGE; @JsonRemoteProperty private String updateCronPattern; @@ -52,16 +50,6 @@ public void setScript(String script) { this.script = script; } - @Override - public boolean isSettable() { - return settable; - } - - @Override - public void setSettable(boolean settable) { - this.settable = settable; - } - public UpdateEventType getUpdateEvent() { return updateEvent; } @@ -97,7 +85,7 @@ public void setExecutionDelayPeriodType(TimePeriodType executionDelayPeriodType) @Override public MetaPointLocatorVO parsePointLocatorData() { MetaPointLocatorVO plVO = new MetaPointLocatorVO(); - plVO.setSettable(this.isSettable()); + plVO.setSettable(this.isSettable() != null ? this.isSettable() : plVO.isSettable()); plVO.setDataTypeId(this.getDataTypeId()); plVO.setContext(this.getContext()); plVO.setScript(this.getScript()); diff --git a/src/org/scada_lts/web/mvc/api/datasources/virtual/VirtualPointLocatorJson.java b/src/org/scada_lts/web/mvc/api/datasources/virtual/VirtualPointLocatorJson.java index 497a1312e9..018ea8871e 100644 --- a/src/org/scada_lts/web/mvc/api/datasources/virtual/VirtualPointLocatorJson.java +++ b/src/org/scada_lts/web/mvc/api/datasources/virtual/VirtualPointLocatorJson.java @@ -117,7 +117,7 @@ public void setAnalogAttractorChange(AnalogAttractorChangeVO analogAttractorChan @Override public VirtualPointLocatorVO parsePointLocatorData() { VirtualPointLocatorVO plVO = new VirtualPointLocatorVO(); - plVO.setSettable(this.isSettable()); + plVO.setSettable(this.isSettable() != null ? this.isSettable() : plVO.isSettable()); plVO.setDataTypeId(this.getDataTypeId()); plVO.setChangeTypeId(this.getChangeTypeId()); plVO.setAlternateBooleanChange(this.getAlternateBooleanChange());