diff --git a/WebContent/WEB-INF/applicationContext.xml b/WebContent/WEB-INF/applicationContext.xml index 57cbc58713..0e94f408f9 100644 --- a/WebContent/WEB-INF/applicationContext.xml +++ b/WebContent/WEB-INF/applicationContext.xml @@ -169,7 +169,7 @@ - + @@ -244,4 +244,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/WebContent/WEB-INF/jsp/systemSettings.jsp b/WebContent/WEB-INF/jsp/systemSettings.jsp index 5a284c0e98..4ed4b1e457 100644 --- a/WebContent/WEB-INF/jsp/systemSettings.jsp +++ b/WebContent/WEB-INF/jsp/systemSettings.jsp @@ -100,6 +100,15 @@ $set("", settings.); $set("", settings.); + + $set("", settings.); + $set("", settings.); + $set("", settings.); + $set("", settings.); + + setDisabled($(""), !settings.); + setDisabled($(""), !settings. || !settings.); + var sel = $(""); sel.options[sel.options.length] = new Option("${lang.value}", "${lang.key}"); @@ -264,6 +273,23 @@ setDisabled($(""), !proxy); setDisabled($(""), !proxy); } + + function workItemsReportingEnabledChange() { + var workItemsReportingEnabled = $("").checked; + if(!workItemsReportingEnabled) { + $set("", false); + workItemsReportingItemsPerSecondEnabledChange(); + } + setDisabled($(""), !workItemsReportingEnabled); + } + + function workItemsReportingItemsPerSecondEnabledChange() { + var workItemsReportingItemsPerSecondEnabled = $("").checked; + if(!workItemsReportingItemsPerSecondEnabled) { + $set("", 0); + } + setDisabled($(""), !workItemsReportingItemsPerSecondEnabled); + } function saveMiscSettings() { SystemSettingsDwr.saveMiscSettings( @@ -273,6 +299,10 @@ $get(""), $get(""), $get(""), + $get(""), + $get(""), + $get(""), + $get(""), function(response) { stopImageFader("saveMiscSettingsImg"); if (response.hasMessages) @@ -888,6 +918,30 @@ "/>" type="number" class="formShort"/> + + + + "/>" type="checkbox" onchange="workItemsReportingEnabledChange()"/> + + + + + + "/>" type="checkbox" onchange="workItemsReportingItemsPerSecondEnabledChange()"/> + + + + + + "/>" type="number" class="formShort"/> + + + + + + "/>" type="number" class="formShort"/> + + diff --git a/WebContent/WEB-INF/spring-security.xml b/WebContent/WEB-INF/spring-security.xml index 9187fc6878..a5801b4979 100644 --- a/WebContent/WEB-INF/spring-security.xml +++ b/WebContent/WEB-INF/spring-security.xml @@ -72,6 +72,50 @@ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + @@ -190,7 +234,6 @@ - @@ -225,7 +268,6 @@ - diff --git a/WebContent/WEB-INF/tags/alarmAck.tag b/WebContent/WEB-INF/tags/alarmAck.tag index 62f8bee706..4216d3ed2b 100644 --- a/WebContent/WEB-INF/tags/alarmAck.tag +++ b/WebContent/WEB-INF/tags/alarmAck.tag @@ -22,7 +22,7 @@ - + diff --git a/build.gradle b/build.gradle index e577577d05..0637e329b1 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,8 @@ plugins { id 'java' } +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = 'UTF-8' sourceCompatibility = 1.11 targetCompatibility = 1.11 @@ -197,5 +199,10 @@ test { includeTestsMatching "org.scada_lts.dao.IsEventDetectorXidUniqueTest" includeTestsMatching "com.serotonin.mango.view.export.CsvWriterTest" includeTestsMatching "com.serotonin.mango.util.EmailValidatorTest" + includeTestsMatching "com.serotonin.mango.vo.LoggedUserTestsSuite" + includeTestsMatching "org.scada_lts.utils.ThreadUtilsTest" + includeTestsMatching "com.serotonin.mango.rt.maint.work.CreateWorkItemToStringTest" + includeTestsMatching "com.serotonin.util.SerializationHelperTest" + includeTestsMatching "org.scada_lts.web.mvc.api.json.WorkItemInfoListTest" } } \ No newline at end of file diff --git a/doc/ThreadInfoAPI.yaml b/doc/ThreadInfoAPI.yaml index 2e436b1c97..cc69b7ae67 100644 --- a/doc/ThreadInfoAPI.yaml +++ b/doc/ThreadInfoAPI.yaml @@ -4,7 +4,7 @@ servers: description: 'Scada development Server' variables: {} info: - version: 2.7.2 + version: 2.7.6.1 title: Scada-LTS API description: 'Scada-LTS OpenAPI Specification. Description contains only a SMS and Email new feature REST API' termsOfService: '' @@ -23,61 +23,61 @@ paths: '200': description: 'Get successful' headers: { } - /threads/stack/: + /threads/metrics/: get: tags: - ThreadInfoAPI - description: 'Get all stacks from threads' + description: 'Get metrics threads' responses: '200': description: 'Get successful' headers: { } - /threads/names/: + /threads/stack/: get: tags: - ThreadInfoAPI - description: 'Get all thread names' + description: 'Get all stacks from threads' responses: '200': description: 'Get successful' headers: { } - /threads/group-by/count/: + /threads/names/: get: tags: - ThreadInfoAPI - description: 'Group threads count by thread' + description: 'Get all thread names' responses: '200': description: 'Get successful' headers: { } - /threads/group-by/thread-stack/: + /threads/classes/: get: tags: - ThreadInfoAPI - description: 'Group stacks by thread' + description: 'Get all thread classes' responses: '200': description: 'Get successful' headers: { } - /threads/group-by/thread-stack/classes/: + /threads/group-by/classes/: get: tags: - ThreadInfoAPI - description: 'Group stack classes by thread' + description: 'Group threads by thread' responses: '200': description: 'Get successful' headers: { } - /threads/group-by/thread-stack/count/: + /threads/group-by/classes/count/: get: tags: - ThreadInfoAPI - description: 'Group stacks count by thread' + description: 'Group threads count by thread' responses: '200': description: 'Get successful' headers: { } - /threads/group-by/stack-thread/: + /threads/group-by/stack/: get: tags: - ThreadInfoAPI @@ -86,7 +86,7 @@ paths: '200': description: 'Get successful' headers: { } - /threads/group-by/stack-thread/classes/: + /threads/group-by/stack/classes/: get: tags: - ThreadInfoAPI @@ -95,7 +95,7 @@ paths: '200': description: 'Get successful' headers: { } - /threads/group-by/stack-thread/count/: + /threads/group-by/stack/count/: get: tags: - ThreadInfoAPI @@ -104,7 +104,7 @@ paths: '200': description: 'Get successful' headers: { } - /threads/group-by/stack-thread/names/: + /threads/group-by/stack/names/: get: tags: - ThreadInfoAPI @@ -113,6 +113,42 @@ paths: '200': description: 'Get successful' headers: { } + /threads/group-by/states/: + get: + tags: + - StateThreadInfoAPI + description: 'Group threads by state' + responses: + '200': + description: 'Get successful' + headers: { } + /threads/group-by/states/classes/: + get: + tags: + - StateThreadInfoAPI + description: 'Group thread classes by state' + responses: + '200': + description: 'Get successful' + headers: { } + /threads/group-by/states/count/: + get: + tags: + - StateThreadInfoAPI + description: 'Group threads count by state' + responses: + '200': + description: 'Get successful' + headers: { } + /threads/group-by/states/names/: + get: + tags: + - StateThreadInfoAPI + description: 'Group thread namew by state' + responses: + '200': + description: 'Get successful' + headers: { } /threads/states/: get: tags: @@ -122,7 +158,7 @@ paths: '200': description: 'Get successful' headers: { } - /threads/states/state/{state}/: + /threads/states/{state}/: get: tags: - StateThreadInfoAPI @@ -138,11 +174,11 @@ paths: schema: type: 'string' enum: [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED] - /threads/states/state/{state}/count/: + /threads/states/{state}/metrics/: get: tags: - StateThreadInfoAPI - description: 'Get threads count for state' + description: 'Get metrics threads for state' responses: '200': description: 'Get successful' @@ -154,7 +190,7 @@ paths: schema: type: 'string' enum: [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED] - /threads/states/state/{state}/classes/: + /threads/states/{state}/classes/: get: tags: - StateThreadInfoAPI @@ -170,7 +206,7 @@ paths: schema: type: 'string' enum: [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED] - /threads/states/state/{state}/names/: + /threads/states/{state}/names/: get: tags: - StateThreadInfoAPI @@ -186,39 +222,3 @@ paths: schema: type: 'string' enum: [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED] - /threads/states/group-by/: - get: - tags: - - StateThreadInfoAPI - description: 'Group threads by state' - responses: - '200': - description: 'Get successful' - headers: { } - /threads/states/group-by/count/: - get: - tags: - - StateThreadInfoAPI - description: 'Group threads count by state' - responses: - '200': - description: 'Get successful' - headers: { } - /threads/states/group-by/classes/: - get: - tags: - - StateThreadInfoAPI - description: 'Group thread classes by state' - responses: - '200': - description: 'Get successful' - headers: { } - /threads/states/group-by/names/: - get: - tags: - - StateThreadInfoAPI - description: 'Group thread namew by state' - responses: - '200': - description: 'Get successful' - headers: { } \ No newline at end of file diff --git a/doc/WorkItemInfoAPI.yaml b/doc/WorkItemInfoAPI.yaml index 34cded218b..423f710302 100644 --- a/doc/WorkItemInfoAPI.yaml +++ b/doc/WorkItemInfoAPI.yaml @@ -4,7 +4,7 @@ servers: description: 'Scada development Server' variables: {} info: - version: 2.7.5 + version: 2.7.6.1 title: Scada-LTS API description: 'Scada-LTS OpenAPI Specification. Description contains only a SMS and Email new feature REST API' termsOfService: '' @@ -15,6 +15,158 @@ info: name: 'GPL-2.0' paths: /work-items/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed and not executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items executed and not executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/priority/{priority}/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/priority/{priority}/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items all filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/priority/{priority}/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/priority/{priority}/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes then metrics' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/priority/{priority}/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes then count' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by class' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by class then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed and not executed by priority then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/not-executed/: get: tags: - WorkItemInfoAPI @@ -23,7 +175,16 @@ paths: '200': description: "Get successful" headers: { } - /work-items/group-by/: + /work-items/not-executed/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items not executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/not-executed/group-by/classes/: get: tags: - WorkItemInfoAPI @@ -32,7 +193,16 @@ paths: '200': description: "Get successful" headers: { } - /work-items/group-by/count/: + /work-items/not-executed/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items not executed by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/not-executed/group-by/classes/count/: get: tags: - WorkItemInfoAPI @@ -41,6 +211,33 @@ paths: '200': description: "Get successful" headers: { } + /work-items/not-executed/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items not executed by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/not-executed/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items not executed by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/not-executed/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items not executed by priority then count' + responses: + '200': + description: "Get successful" + headers: { } /work-items/executed/: get: tags: @@ -50,7 +247,16 @@ paths: '200': description: "Get successful" headers: { } - /work-items/executed/group-by/: + /work-items/executed/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/executed/group-by/classes/: get: tags: - WorkItemInfoAPI @@ -59,124 +265,124 @@ paths: '200': description: "Get successful" headers: { } - /work-items/executed/group-by/count/: + /work-items/executed/group-by/classes/metrics/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items executed by class then count' + description: 'Grouping work items executed by class then statistic' responses: '200': description: "Get successful" headers: { } - /work-items/failed/: + /work-items/executed/group-by/classes/count/: get: tags: - WorkItemInfoAPI - description: 'Get work items fail executed' + description: 'Grouping work items executed by class then count' responses: '200': description: "Get successful" headers: { } - /work-items/failed/group-by/: + /work-items/executed/group-by/priority/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items fail executed by class' + description: 'Grouping work items executed by priority' responses: '200': description: "Get successful" headers: { } - /work-items/failed/group-by/count/: + /work-items/executed/group-by/priority/metrics/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items fail executed by class then count' + description: 'Grouping work items executed by priority then statistic' responses: '200': description: "Get successful" headers: { } - /work-items/running/: + /work-items/executed/group-by/priority/count/: get: tags: - WorkItemInfoAPI - description: 'Get work items running' + description: 'Grouping work items executed by priority then count' responses: '200': description: "Get successful" headers: { } - /work-items/running/group-by/: + /work-items/executed/success/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items running by class' + description: 'Get work items success' responses: '200': description: "Get successful" headers: { } - /work-items/running/group-by/count/: + /work-items/executed/success/metrics/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items running by class then count' + description: 'Get metrics work items success' responses: '200': description: "Get successful" headers: { } - /work-items/success/: + /work-items/executed/success/group-by/classes/: get: tags: - WorkItemInfoAPI - description: 'Get work items success executed' + description: 'Grouping work items success by class' responses: '200': description: "Get successful" headers: { } - /work-items/success/group-by/: + /work-items/executed/success/group-by/classes/metrics/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items success executed by class' + description: 'Grouping work items success by class then metrics' responses: '200': description: "Get successful" headers: { } - /work-items/success/group-by/count/: + /work-items/executed/success/group-by/classes/count/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items success executed by class then count' + description: 'Grouping work items success by class then count' responses: '200': description: "Get successful" headers: { } - /work-items/all/: + /work-items/executed/success/group-by/priority/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed and not executed' + description: 'Grouping work items success by priority' responses: '200': description: "Get successful" headers: { } - /work-items/all/group-by/: + /work-items/executed/success/group-by/priority/metrics/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items all by class' + description: 'Grouping work items success by priority then metrics' responses: '200': description: "Get successful" headers: { } - /work-items/all/group-by/count/: + /work-items/executed/success/group-by/priority/count/: get: tags: - WorkItemInfoAPI - description: 'Grouping work items all by class then count' + description: 'Grouping work items success by priority then count' responses: '200': description: "Get successful" headers: { } - /work-items/longer/{executedMs}/: + /work-items/executed/longer/{executedMs}/: get: tags: - WorkItemInfoAPI @@ -191,11 +397,11 @@ paths: required: true schema: type: 'integer' - /work-items/longer/{executedMs}/group-by/: + /work-items/executed/longer/{executedMs}/metrics/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed longer than executedMs by class' + description: 'Get metrics work items executed longer than executedMs' responses: '200': description: "Get successful" @@ -206,11 +412,11 @@ paths: required: true schema: type: 'integer' - /work-items/longer/{executedMs}/group-by/count/: + /work-items/executed/longer/{executedMs}/group-by/classes/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed longer than executedMs by class then count' + description: 'Get work items executed longer than executedMs by class' responses: '200': description: "Get successful" @@ -221,11 +427,11 @@ paths: required: true schema: type: 'integer' - /work-items/longer/{executedMs}/history/: + /work-items/executed/longer/{executedMs}/group-by/classes/metrics/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed longer than executedMs from History' + description: 'Get work items executed longer than executedMs by class then metrics' responses: '200': description: "Get successful" @@ -236,11 +442,11 @@ paths: required: true schema: type: 'integer' - /work-items/longer/{executedMs}/history/group-by/: + /work-items/executed/longer/{executedMs}/group-by/classes/count/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed longer than executedMs by class from History' + description: 'Get work items executed longer than executedMs by class then count' responses: '200': description: "Get successful" @@ -251,11 +457,11 @@ paths: required: true schema: type: 'integer' - /work-items/longer/{executedMs}/history/group-by/count/: + /work-items/executed/longer/{executedMs}/group-by/priority/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed longer than executedMs by class then count from History' + description: 'Get work items executed longer than executedMs by priority' responses: '200': description: "Get successful" @@ -266,11 +472,11 @@ paths: required: true schema: type: 'integer' - /work-items/less/{executedMs}/: + /work-items/executed/longer/{executedMs}/group-by/priority/metrics/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed less than executedMs' + description: 'Get work items executed longer than executedMs by priority then metrics' responses: '200': description: "Get successful" @@ -281,11 +487,11 @@ paths: required: true schema: type: 'integer' - /work-items/less/{executedMs}/group-by/: + /work-items/executed/longer/{executedMs}/group-by/priority/count/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed less than executedMs by class' + description: 'Get work items executed longer than executedMs by priority then count' responses: '200': description: "Get successful" @@ -296,11 +502,11 @@ paths: required: true schema: type: 'integer' - /work-items/less/{executedMs}/group-by/count/: + /work-items/executed/less/{executedMs}/: get: tags: - WorkItemInfoAPI - description: 'Get work items executed less than executedMs by class then count' + description: 'Get work items executed less than executedMs' responses: '200': description: "Get successful" @@ -311,102 +517,813 @@ paths: required: true schema: type: 'integer' - /work-items/priority/{priority}/: + /work-items/executed/less/{executedMs}/metrics/: get: tags: - WorkItemInfoAPI - description: 'Get work items all filtering by priority' + description: 'Get metrics work items executed less than executedMs' responses: '200': description: "Get successful" headers: { } parameters: - - name: 'priority' + - name: 'executedMs' in: 'path' required: true schema: - type: 'string' - enum: [ HIGH, MEDIUM, LOW ] - /work-items/priority/{priority}/group-by/: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/classes/: get: tags: - WorkItemInfoAPI - description: 'Get work items all filtering by priority grouping by class' + description: 'Get work items executed less than executedMs by class' responses: '200': description: "Get successful" headers: { } parameters: - - name: 'priority' + - name: 'executedMs' in: 'path' required: true schema: - type: 'string' - enum: [ HIGH, MEDIUM, LOW ] - /work-items/priority/{priority}/group-by/count/: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/classes/metrics/: get: tags: - WorkItemInfoAPI - description: 'Get work items all filtering by priority grouping by class then count' + description: 'Get work items executed less than executedMs by class then metrics' responses: '200': description: "Get successful" headers: { } parameters: - - name: 'priority' + - name: 'executedMs' in: 'path' required: true schema: - type: 'string' - enum: [ HIGH, MEDIUM, LOW ] - /work-items/scheduled/: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/classes/count/: get: tags: - - ScheduledWorkItemInfoAPI - description: 'Get active scheduled work items' + - WorkItemInfoAPI + description: 'Get work items executed less than executedMs by class then count' responses: '200': description: "Get successful" headers: { } - /work-items/scheduled/group-by/: + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/priority/: get: tags: - - ScheduledWorkItemInfoAPI - description: 'Grouping active scheduled work items by class' + - WorkItemInfoAPI + description: 'Get work items executed less than executedMs by priority' responses: '200': description: "Get successful" headers: { } - /work-items/scheduled/group-by/count/: + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/priority/metrics/: get: tags: - - ScheduledWorkItemInfoAPI - description: 'Grouping active scheduled work items by class then count' + - WorkItemInfoAPI + description: 'Get work items executed less than executedMs by priority then metrics' responses: '200': description: "Get successful" headers: { } - /work-items/scheduled/state/{state}/: + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/executed/less/{executedMs}/group-by/priority/count/: get: tags: - - ScheduledWorkItemInfoAPI - description: 'Get active scheduled work items' + - WorkItemInfoAPI + description: 'Get work items executed less than executedMs by priority then count' responses: '200': description: "Get successful" headers: { } parameters: - - name: 'state' + - name: 'executedMs' in: 'path' required: true schema: - type: 'string' - enum: [ VIRGIN, CANCELLED, EXECUTED, SCHEDULED ] - /work-items/scheduled/state/{state}/group-by/: + type: 'integer' + /work-items/executed/priority/{priority}/: get: tags: - - ScheduledWorkItemInfoAPI - description: 'Grouping active scheduled work items by class' + - WorkItemInfoAPI + description: 'Get work items executed filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/executed/priority/{priority}/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items executed filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/executed/priority/{priority}/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed filtering by priority grouping by class' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/executed/priority/{priority}/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed filtering by priority grouping by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/executed/priority/{priority}/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed filtering by priority grouping by class then count' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/longer/{executedMs}/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items executed longer than executedMs from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by class from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by class from History then metrics' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by class then count from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by priority from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by priority from History then metrics' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/longer/{executedMs}/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed longer than executedMs by priority then count from History' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'executedMs' + in: 'path' + required: true + schema: + type: 'integer' + /work-items/history/priority/{priority}/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/priority/{priority}/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items all filtering by priority' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/priority/{priority}/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/priority/{priority}/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes then metrics' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/priority/{priority}/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items all filtering by priority and group by classes then count' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'priority' + in: 'path' + required: true + schema: + type: 'string' + enum: [ HIGH, MEDIUM, LOW ] + /work-items/history/process/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics process work items' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by classes' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by classes then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by classes then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/process/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Get process work items and group by priority then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by class' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by class then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items executed by priority then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items fail executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items fail executed' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by class' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by class then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/history/failed/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items fail executed by priority then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/: + get: + tags: + - WorkItemInfoAPI + description: 'Get work items running' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Get metrics work items running' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/classes/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by class' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/classes/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/classes/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by class then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/priority/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by priority' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/priority/metrics/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by priority then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/running/group-by/priority/count/: + get: + tags: + - WorkItemInfoAPI + description: 'Grouping work items running by priority then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Get active scheduled work items' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/metrics/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Get metrics active scheduled work items' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/classes/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by class' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/classes/metrics/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by class then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/classes/count/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by class then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/states/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by states' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/states/metrics/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by states then metrics' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/group-by/states/count/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by states then count' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/states/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Get states scheduled work items' + responses: + '200': + description: "Get successful" + headers: { } + /work-items/scheduled/states/{state}/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Get active scheduled work items' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'state' + in: 'path' + required: true + schema: + type: 'string' + enum: [ VIRGIN, CANCELLED, EXECUTED, SCHEDULED ] + /work-items/scheduled/states/{state}/metrics/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Get metrics active scheduled work items' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'state' + in: 'path' + required: true + schema: + type: 'string' + enum: [ VIRGIN, CANCELLED, EXECUTED, SCHEDULED ] + /work-items/scheduled/states/{state}/group-by/classes/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by class' + responses: + '200': + description: "Get successful" + headers: { } + parameters: + - name: 'state' + in: 'path' + required: true + schema: + type: 'string' + enum: [ VIRGIN, CANCELLED, EXECUTED, SCHEDULED ] + /work-items/scheduled/states/{state}/group-by/classes/metrics/: + get: + tags: + - ScheduledWorkItemInfoAPI + description: 'Grouping active scheduled work items by class then metrics' responses: '200': description: "Get successful" @@ -418,7 +1335,7 @@ paths: schema: type: 'string' enum: [ VIRGIN, CANCELLED, EXECUTED, SCHEDULED ] - /work-items/scheduled/state/{state}/group-by/count/: + /work-items/scheduled/states/{state}/group-by/classes/count/: get: tags: - ScheduledWorkItemInfoAPI diff --git a/scadalts-ui/src/locales/en.json b/scadalts-ui/src/locales/en.json index 59013031af..fb15c667e4 100644 --- a/scadalts-ui/src/locales/en.json +++ b/scadalts-ui/src/locales/en.json @@ -1055,5 +1055,9 @@ "userDetails.view.enableFullScreen": "Enable full screen mode", "userDetails.view.hideShortcutDisableFullScreen": "Hide shortcut to disable full screen", "systemsettings.event.pendingLimit": "Event Pending Limit", - "systemsettings.event.pendingCacheEnabled": "Enabled Event Pending Cache" + "systemsettings.event.pendingCacheEnabled": "Enabled Event Pending Cache", + "systemsettings.workitems.reporting.enabled": "Work items reporting enabled", + "systemsettings.workitems.reporting.itemspersecond.enabled": "Items per second reporting enabled", + "systemsettings.workitems.reporting.itemspersecond.limit": "Items per second reporting limit", + "systemsettings.threads.name.additional.length": "Thread name length" } diff --git a/scadalts-ui/src/views/System/SystemSettings/MiscSettingsComponent.vue b/scadalts-ui/src/views/System/SystemSettings/MiscSettingsComponent.vue index eb0cf2112f..816f087a31 100644 --- a/scadalts-ui/src/views/System/SystemSettings/MiscSettingsComponent.vue +++ b/scadalts-ui/src/views/System/SystemSettings/MiscSettingsComponent.vue @@ -61,6 +61,38 @@ dense > + + + + + + + + + + + + diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java b/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java index 2d858db73a..828acf6b10 100644 --- a/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java +++ b/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java @@ -18,8 +18,8 @@ public class DNP3Master { private DNPUser user; private int relativePollingPeriod = 10; private int pollingCount = 0; - private int timeoutCount = 0; - private int timeoutsToReconnect = 3; + private volatile int timeoutCount = 0; + private final int timeoutsToReconnect = 3; public void initEthernet(int sourceAddress, int slaveAddress, String host, int port, int relativePollingPeriod) throws Exception { @@ -39,8 +39,13 @@ public void initSerial(int sourceAddress, int slaveAddress, String com, DNPConfig config = new DNPConfig(parameters, sourceAddress, slaveAddress); user = new DNPUser(config); - - user.init(); + try { + user.init(); + } catch (Error e) { + log.fatal(e.getMessage(), e); + } catch (Exception e) { + log.error(e.getMessage(), e); + } } private boolean reconnecting = false; @@ -54,17 +59,17 @@ public void doPoll() throws Exception { user.init(); reconnecting = false; log.debug("[DNP3Master] Reconnected!"); - } catch (Exception e) { + } catch (Exception | Error e) { + log.warn(e.getMessage(), e); terminate(); } } catch (Exception e) { - e.printStackTrace(); + throw e; } } else { if (reconnectNeeded()) { reconnecting = true; - System.out - .println("[DNP3Master] Conexão falhou. Terminar Conexão."); + log.debug("[DNP3Master] Conexão falhou. Terminar Conexão."); terminate(); log.debug("[DNP3Master] Conexão terminada."); throw new Exception("[DNP3Master] Poll failed!"); @@ -106,7 +111,13 @@ public List read(int group, int index) { } public void terminate() throws Exception { - user.stop(); + try { + user.stop(); + } catch (Exception ex) { + if(ex instanceof NullPointerException) + throw new Exception(this.getClass().getSimpleName() + " error terminate. It probably failed to initialize." , ex); + throw ex; + } } public void sendAnalogCommand(int index, int value) throws Exception { diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java index 15e51a80f8..8a28831d8b 100644 --- a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java +++ b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java @@ -45,10 +45,11 @@ protected void doPoll(long time) { dnp3Master.doPoll(); returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time); } catch (Exception e) { - e.printStackTrace(); + LOG.warn(e.getMessage(), e); raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true, new LocalizableMessage("event.exception2", vo.getName(), e .getMessage())); + return; } for (DataPointRT dataPoint : dataPoints) { @@ -85,7 +86,7 @@ public void terminate() { raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true, new LocalizableMessage("event.exception2", vo.getName(), e .getMessage())); - e.printStackTrace(); + LOG.error(e.getMessage(), e); } } diff --git a/src/br/org/scadabr/view/component/AlarmListComponent.java b/src/br/org/scadabr/view/component/AlarmListComponent.java index 6241cf93af..b60cb78fc8 100644 --- a/src/br/org/scadabr/view/component/AlarmListComponent.java +++ b/src/br/org/scadabr/view/component/AlarmListComponent.java @@ -58,7 +58,7 @@ public String generateContent() { WebContext webContext = WebContextFactory.get(); HttpServletRequest request = webContext.getHttpServletRequest(); List toViewEvents = new EventService().getPendingEventsAlarmLevelMin(Common - .getUser().getId(), minAlarmLevel, maxListSize, true); + .getUser().getId(), minAlarmLevel, maxListSize); model.put("nome", "marlon"); model.put("events",toViewEvents); diff --git a/src/br/org/scadabr/view/component/ChartComparatorComponent.java b/src/br/org/scadabr/view/component/ChartComparatorComponent.java index fa68fce774..ec11fbcc88 100644 --- a/src/br/org/scadabr/view/component/ChartComparatorComponent.java +++ b/src/br/org/scadabr/view/component/ChartComparatorComponent.java @@ -12,12 +12,15 @@ import com.serotonin.json.JsonRemoteEntity; import com.serotonin.json.JsonRemoteProperty; -import com.serotonin.mango.db.dao.DataPointDao; +import com.serotonin.mango.Common; import com.serotonin.mango.view.ImplDefinition; import com.serotonin.mango.view.component.HtmlComponent; import com.serotonin.mango.view.component.ViewComponent; -import com.serotonin.mango.vo.DataPointVO; +import com.serotonin.mango.vo.User; import com.serotonin.util.SerializationHelper; +import org.scada_lts.dao.DataPointDAO; +import org.scada_lts.dao.model.ScadaObjectIdentifier; +import org.scada_lts.permissions.service.GetDataPointsWithAccess; @JsonRemoteEntity public class ChartComparatorComponent extends HtmlComponent { @@ -61,11 +64,13 @@ public String createChartComparatorContent() { // sb.append("
"); sb.append("
"); - - sb.append(createDataPointsSelectComponent(idPrefix + "_dp1")); - sb.append(createDataPointsSelectComponent(idPrefix + "_dp2")); - sb.append(createDataPointsSelectComponent(idPrefix + "_dp3")); - sb.append(createDataPointsSelectComponent(idPrefix + "_dp4")); + GetDataPointsWithAccess dataPointsWithAccess = new GetDataPointsWithAccess(new DataPointDAO()); + User user = Common.getUser(); + List dataPoints = dataPointsWithAccess.getObjectIdentifiersWithAccess(user); + sb.append(createDataPointsSelectComponent(idPrefix + "_dp1", dataPoints)); + sb.append(createDataPointsSelectComponent(idPrefix + "_dp2", dataPoints)); + sb.append(createDataPointsSelectComponent(idPrefix + "_dp3", dataPoints)); + sb.append(createDataPointsSelectComponent(idPrefix + "_dp4", dataPoints)); sb.append("
"); sb.append("
"); @@ -99,16 +104,15 @@ public String createChartComparatorContent() { return sb.toString(); } - private String createDataPointsSelectComponent(String idPrefix) { - List dataPoints = new DataPointDao().getDataPoints(null, - false); + private String createDataPointsSelectComponent(String idPrefix, List dataPoints) { + StringBuilder sb = new StringBuilder(); sb.append("