From b39e27ede8238ef63440810a8327b927c4c43ac0 Mon Sep 17 00:00:00 2001 From: Ioakeim Samaras Date: Wed, 3 Jul 2019 14:43:32 +0300 Subject: [PATCH] [UI] UI enhancements - Representation of declarative result info - Re-deployment of db when persistent storage already exists - Searching matching fields should be supported in the front-end app - Loading gif should be displayed when the front-end apps is trying to receive results - Deletion of submissions should be disabled JIRA: VAL-37 Signed-off-by: Ioakeim Samaras Change-Id: Ie140cd595543790c90ab60d50288cc825bd07a6b --- .coafile | 4 +- docker/README.rst | 51 ++- docker/mariadb/Dockerfile | 2 +- docker/mariadb/deploy.sh | 4 +- .../deploy_with_existing_persistent_storage.sh | 51 +++ ui/CHANGELOG.md | 21 + ui/README.rst | 68 ++- ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql | 4 + ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql | 14 + ui/db-scripts/akraino-blueprint_validation_db.sql | 117 ----- ui/db-scripts/akraino_blueprint_validation_db.sql | 92 ++++ ui/pom.xml | 5 +- .../ui/client/jenkins/resources/CrumbResponse.java | 24 +- .../ui/client/jenkins/resources/QueueJobItem.java | 34 +- .../ui/client/nexus/NexusExecutorClient.java | 3 + .../validation/ui/client/nexus/resources/Kw.java | 136 ++++++ .../ui/client/nexus/resources/RobotTestResult.java | 194 +++++++-- .../validation/ui/client/nexus/resources/Test.java | 146 +++++++ .../ui/controller/SubmissionController.java | 12 - .../AECCommittedSubmissionsController.js | 23 - .../CommittedSubmissionsTemplate.html | 94 ++-- .../AECGetBySubmissionIdController.js | 45 +- .../GetBySubmissionIdTemplate.html | 478 ++++++++++++++------- .../NewSubmission/AECNewSubmissionController.js | 15 +- ui/src/main/webapp/static/fusion/images/giphy.gif | Bin 0 -> 8821 bytes 25 files changed, 1188 insertions(+), 449 deletions(-) create mode 100755 docker/mariadb/deploy_with_existing_persistent_storage.sh delete mode 100644 ui/db-scripts/akraino-blueprint_validation_db.sql create mode 100644 ui/db-scripts/akraino_blueprint_validation_db.sql create mode 100644 ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Kw.java create mode 100644 ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Test.java create mode 100644 ui/src/main/webapp/static/fusion/images/giphy.gif diff --git a/.coafile b/.coafile index 0514a52..5096c4b 100644 --- a/.coafile +++ b/.coafile @@ -51,7 +51,9 @@ ignore = ui/target/**, ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppInitializer.java, ui/src/main/java/org/akraino/validation/ui/scheduler/RegistryAdapter.java, ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppConfig.java, - ui/src/main/java/org/akraino/validation/ui/filter/SecurityXssFilter.java + ui/src/main/java/org/akraino/validation/ui/filter/SecurityXssFilter.java, + ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/**.java, + ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/**.java [all.JS] bears = ESLintBear,JSComplexityBear diff --git a/docker/README.rst b/docker/README.rst index 5da7288..12c75be 100644 --- a/docker/README.rst +++ b/docker/README.rst @@ -108,14 +108,38 @@ TAG_PRE, first part of the image version, default value is mariadb TAG_VER, last part of the image version, default value is latest MARIADB_HOST_PORT, port on which mariadb is exposed on host, default value is 3307 -If you want to deploy the container, you can run this script with the appropriate parameters. +In order to deploy the container, this script can be executed with the appropriate parameters. -Example (assuming you have used the default variables for building the image using the make command): +Example (assuming the default variables have been utilized for building the image using the make command): .. code-block:: console + cd validation/docker/mariadb ./deploy.sh MARIADB_ROOT_PASSWORD=password UI_ADMIN_PASSWORD=admin UI_AKRAINO_PASSWORD=akraino +Also, in order to re-deploy the database (it is assumed that the corresponding mariadb container has been stopped and deleted) while the persistent storage already exists (currently, the directory /var/lib/mariadb of the host is used), a different approach should be used after the image build process. + +To this end, another script has been developed, namely deploy_with_existing_storage.sh which easily deploys the container. This script accepts the following items as input parameters: + +CONTAINER_NAME, the name of the container, default value is akraino-validation-mariadb +MARIADB_ROOT_PASSWORD, the desired mariadb root user password, this variable is required +REGISTRY, the registry of the mariadb image, default value is akraino +NAME, the name of the mariadb image, default value is validation +TAG_PRE, the first part of the image version, default value is mariadb +TAG_VER, the last part of the image version, default value is latest +MARIADB_HOST_PORT, the port on which mariadb is exposed on host, default value is 3307 + +In order to deploy the container, this script can be executed with the appropriate parameters. + +Example (assuming the default variables have been utilized for building the image using the make command): + +.. code-block:: console + + cd validation/docker/mariadb + ./deploy_with_existing_persistent_storage.sh MARIADB_ROOT_PASSWORD=password + +More info can be found at the UI README file. + The ui container ================ @@ -138,19 +162,19 @@ Using the container ------------------- In order for the container to be easily created, the deploy.sh script has been developed. This script accepts the following as input parameters: -CONTAINER_NAME, name of the contaner, default value is akraino-validation-ui +CONTAINER_NAME, the name of the contaner, default value is akraino-validation-ui DB_CONNECTION_URL, the URL connection with the akraino database of the maridb instance, this variable is required -MARIADB_ROOT_PASSWORD, mariadb root user password, this variable is required -REGISTRY, registry of the mariadb image, default value is akraino -NAME, name of the mariadb image, default value is validation -TAG_PRE, first part of the image version, default value is ui -TAG_VER, last part of the image version, default value is latest +MARIADB_ROOT_PASSWORD, the mariadb root user password, this variable is required +REGISTRY, the registry of the mariadb image, default value is akraino +NAME, the name of the mariadb image, default value is validation +TAG_PRE, the first part of the image version, default value is ui +TAG_VER, the last part of the image version, default value is latest JENKINS_URL, the URL of the Jenkins instance, this variable is required JENKINS_USERNAME, the Jenkins user name, this variable is required JENKINS_USER_PASSWORD, the Jenkins user password, this variable is required JENKINS_JOB_NAME, the name of Jenkins job capable of executing the blueprint validation tests, this variable is required -NEXUS_PROXY, the proxy needed in order for the Nexus server to be reachable, default value is none -JENKINS_PROXY, the proxy needed in order for the Jenkins server to be reachable, default value is none +NEXUS_PROXY, the needed proxy in order for the Nexus server to be reachable, default value is none +JENKINS_PROXY, the needed proxy in order for the Jenkins server to be reachable, default value is none Note that, for a functional UI, the following prerequisites are needed: @@ -158,14 +182,15 @@ Note that, for a functional UI, the following prerequisites are needed: - A Jenkins instance capable of running the blueprint validation test - A Nexus repo in which all the test results are stored. -Look at the UI README file for more info. +More info can be found at the UI README file. -If you want to deploy the container, you can run the aforementioned script with the appropriate parameters. +In order to deploy the container, the aforementioned script can be executed with the appropriate parameters. -Example (assuming you have used the default variables for building the image using the make command): +Example (assuming the default variables have been utilized for building the image using the make command): .. code-block:: console + cd validation/docker/ui ./deploy.sh DB_CONNECTION_URL=172.17.0.3:3306/akraino MARIADB_ROOT_PASSWORD=password JENKINS_URL=http://192.168.2.2:8080 JENKINS_USERNAME=name JENKINS_USER_PASSWORD=jenkins_pwd JENKINS_JOB_NAME=job1 The kube-conformance container diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile index a2a1b19..52a0f52 100644 --- a/docker/mariadb/Dockerfile +++ b/docker/mariadb/Dockerfile @@ -23,4 +23,4 @@ COPY --from=0 /opt/akraino/validation/ui/db-scripts/EcompSdkDDLMySql_2_4_Common. COPY --from=0 /opt/akraino/validation/ui/db-scripts/EcompSdkDDLMySql_2_4_OS.sql /docker-entrypoint-initdb.d COPY --from=0 /opt/akraino/validation/ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql /docker-entrypoint-initdb.d COPY --from=0 /opt/akraino/validation/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql /docker-entrypoint-initdb.d -COPY --from=0 /opt/akraino/validation/ui/db-scripts/akraino-blueprint_validation_db.sql /docker-entrypoint-initdb.d +COPY --from=0 /opt/akraino/validation/ui/db-scripts/akraino_blueprint_validation_db.sql /docker-entrypoint-initdb.d diff --git a/docker/mariadb/deploy.sh b/docker/mariadb/deploy.sh index 12c985c..fec5a2c 100755 --- a/docker/mariadb/deploy.sh +++ b/docker/mariadb/deploy.sh @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Use this script if the persistent storage does not exist + # Directory on host in where database data will be stored HOST_STORAGE_DIR="/var/lib/mariadb" # Container name @@ -68,4 +70,4 @@ fi IMAGE="$REGISTRY"/"$NAME":"$TAG_PRE"-"$TAG_VER" docker run --detach --name $CONTAINER_NAME --publish $MARIADB_HOST_PORT:3306 --volume $HOST_STORAGE_DIR:/var/lib/mysql -v "/$(pwd)/mariadb.conf:/etc/mysql/conf.d/my.cnf" -e MYSQL_ROOT_PASSWORD="$MARIADB_ROOT_PASSWORD" -e UI_ADMIN_PASSWORD="$UI_ADMIN_PASSWORD" -e UI_AKRAINO_PASSWORD="$UI_AKRAINO_PASSWORD" $IMAGE sleep 10 -docker exec $CONTAINER_NAME /bin/bash -c 'sed -i 's/admin_password/'"$UI_ADMIN_PASSWORD"'/g' /docker-entrypoint-initdb.d/EcompSdkDMLMySql_2_4_OS.sql ; sed -i 's/akraino_password/'"$UI_AKRAINO_PASSWORD"'/g' /docker-entrypoint-initdb.d/akraino-blueprint_validation_db.sql; continue=`ps aux | grep mysql` ; while [ -z "$continue" ]; do continue=`ps aux | grep mysql`; sleep 5; done ; sleep 10 ;' +docker exec $CONTAINER_NAME /bin/bash -c 'sed -i 's/admin_password/'"$UI_ADMIN_PASSWORD"'/g' /docker-entrypoint-initdb.d/EcompSdkDMLMySql_2_4_OS.sql ; sed -i 's/akraino_password/'"$UI_AKRAINO_PASSWORD"'/g' /docker-entrypoint-initdb.d/EcompSdkDMLMySql_2_4_OS.sql; continue=`ps aux | grep mysql` ; while [ -z "$continue" ]; do continue=`ps aux | grep mysql`; sleep 5; done ; sleep 10 ;' diff --git a/docker/mariadb/deploy_with_existing_persistent_storage.sh b/docker/mariadb/deploy_with_existing_persistent_storage.sh new file mode 100755 index 0000000..a20be5b --- /dev/null +++ b/docker/mariadb/deploy_with_existing_persistent_storage.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (c) 2019 AT&T Intellectual Property. All other rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Use this script if the persistent storage already exists and you want to use its data + +# Directory on host in where database data are stored +HOST_STORAGE_DIR="/var/lib/mariadb" +# Container name +CONTAINER_NAME="akraino-validation-mariadb" +# Container input variables +MARIADB_ROOT_PASSWORD="" +# Image data +REGISTRY=akraino +NAME=validation +TAG_PRE=mariadb +TAG_VER=latest +MARIADB_HOST_PORT=3307 + +for ARGUMENT in "$@" +do + KEY=$(echo $ARGUMENT | cut -f1 -d=) + VALUE=$(echo $ARGUMENT | cut -f2 -d=) + case "$KEY" in + REGISTRY) REGISTRY=${VALUE} ;; + NAME) NAME=${VALUE} ;; + TAG_VER) TAG_VER=${VALUE} ;; + TAG_PRE) TAG_PRE=${VALUE} ;; + CONTAINER_NAME) CONTAINER_NAME=${VALUE} ;; + MARIADB_HOST_PORT) MARIADB_HOST_PORT=${VALUE} ;; + MARIADB_ROOT_PASSWORD) MARIADB_ROOT_PASSWORD=${VALUE} ;; + *) + esac +done + +IMAGE="$REGISTRY"/"$NAME":"$TAG_PRE"-"$TAG_VER" +docker run --detach --name $CONTAINER_NAME --publish $MARIADB_HOST_PORT:3306 --volume $HOST_STORAGE_DIR:/var/lib/mysql -v "/$(pwd)/mariadb.conf:/etc/mysql/conf.d/my.cnf" -e MYSQL_ROOT_PASSWORD="$MARIADB_ROOT_PASSWORD" $IMAGE +sleep 10 +docker exec $CONTAINER_NAME /bin/bash -c 'rm -rf /docker-entrypoint-initdb.d/*.sql' diff --git a/ui/CHANGELOG.md b/ui/CHANGELOG.md index beb7192..ac72112 100644 --- a/ui/CHANGELOG.md +++ b/ui/CHANGELOG.md @@ -95,3 +95,24 @@ All notable changes to this project will be documented in this file. - Definition of system architecture removed from the pom.xml ### Removed + +## [0.1.0-SNAPSHOT] - 8 Jule 2019 +### Added +- Declarative info of the results is now displayed +- README enhanced in order to display instructions regarding how each docker image can be built independently. +- A new script, namely validation/docker/mariadb/deploy_with_existing_persistent_storage.sh has been developed in order to deploy the mariadb container when the persistent storage already exists. README files have been updated accordingly. +- Searching matching fields have been added to the angularJS application +- The angularJS application displays the submission id received from the back-end system +- Whenever a new blueprint instance for validation is submitted, the corresponding labels are deleted +- Scroll up/down feature is supported for the committed submissions +- Loading gif is displayed while the angularJS application is trying to fetch results +- Sanity checks in angularJS app + +### Changed +- /db-scripts/akraino-blueprint_validation_db.sql has been renamed to /db-scripts/akraino_blueprint_validation_db.sql +- User info declaration has been moved from the /db-scripts/akraino-blueprint_validation_db.sql and placed into /db-scripts/EcompSdkDMLMySql_2_4_Common.sql and /db-scripts/EcompSdkDMLMySql_2_4_OS.sql +- Results can be retrieved only for submissions whose state is 'Completed' +- README file has been updated to use impersonal phrases + +### Removed +- Deletion of submissions diff --git a/ui/README.rst b/ui/README.rst index afb7c16..eae8f30 100644 --- a/ui/README.rst +++ b/ui/README.rst @@ -87,7 +87,7 @@ A mariadb database instance is needed for both modes of the UI with the appropri The pom.xml file supports the creation of an appropriate docker image for development purposes. The initialization scripts reside under the db-scripts directory. -Also, a script has been developed, namely validation/docker/mariadb/deploy.sh which easily deploys the container. This script accepts the following as input parameters: +Also, a script has been developed, namely validation/docker/mariadb/deploy.sh which easily deploys the container. This script accepts the following items as input parameters: CONTAINER_NAME, name of the container, default value is akraino-validation-mariadb MARIADB_ROOT_PASSWORD, the desired mariadb root user password, this variable is required @@ -101,33 +101,57 @@ MARIADB_HOST_PORT, port on which mariadb is exposed on host, default value is 33 Currently, two users are supported for the UI, namely admin (full privileges) and akraino (limited privileges). Their passwords must be defined in the database. -Let's build and deploy the image using only the required parameters. +In order to build and deploy the image using only the required parameters, the below instructions should be followed: -Configure the mariadb root user password (currently the UI connects to the database using root privileges), the UI admin password and the UI akraino password in the appropriate variables and execute the following commands in order to build and deploy this database container: +The mariadb root user password (currently the UI connects to the database using root privileges), the UI admin password and the UI akraino password should be configured using the appropriate variables and the following commands should be executed: .. code-block:: console cd validation/ui - mvn docker:build + mvn docker:build -Ddocker.filter=akraino/validation:dev-mariadb-latest cd ../docker/mariadb ./deploy.sh TAG_PRE=dev-mariadb MARIADB_ROOT_PASSWORD= UI_ADMIN_PASSWORD= UI_AKRAINO_PASSWORD= mysql -p -uroot -h < ../../ui/db-scripts/examples/initialize_db_example.sql -In order to retrieve the IP of the mariadb container, execute the following command: +In order to retrieve the IP of the mariadb container, the following command should be executed: .. code-block:: console docker inspect -It should be noted that, currently, both images (UI and mariadb) are built using the mvn docker:build command. +Furthermore, the TAG_PRE variable should be defined because the default value is 'mariadb' (note that the 'dev-mariadb' is used for development purposes - look at pom.xml file). -Furthermore, the TAG_PRE variable should be defined as the default value is 'mariadb' (note that the 'dev-mariadb' is used for development purposes - look at pom.xml file). +If the database must be re-deployed (it is assumed that the corresponding mariadb container has been stopped and deleted) while the persistent storage already exists (currently, the directory /var/lib/mariadb of the host is used), a different approach should be used after the image build process. -If you want to re-deploy the database, you must first delete the container and the directory on the host machine where data are stored. To this end, execute the following command: +To this end, another script has been developed, namely validation/docker/mariadb/deploy_with_existing_storage.sh which easily deploys the container. This script accepts the following as input parameters: + +CONTAINER_NAME, the name of the container, default value is akraino-validation-mariadb +MARIADB_ROOT_PASSWORD, the desired mariadb root user password, this variable is required +REGISTRY, the registry of the mariadb image, default value is akraino +NAME, the name of the mariadb image, default value is validation +TAG_PRE, the first part of the image version, default value is mariadb +TAG_VER, the last part of the image version, default value is latest +MARIADB_HOST_PORT, the port on which mariadb is exposed on host, default value is 3307 + +In order to deploy the image using only the required parameters and the existing persistent storage, the below instructions should be followed: + +The mariadb root user password (currently the UI connects to the database using root privileges) should be configured using the appropriate variable and the following commands should be executed: + +.. code-block:: console + + cd validation/docker/mariadb + ./deploy_with_existing_persistent_storage.sh TAG_PRE=dev-mariadb MARIADB_ROOT_PASSWORD= + +Finally, if the database must be re-deployed (it is assumed that the corresponding mariadb container has been stopped and deleted) and the old persistent storage must be deleted, the directory on the host machine where data is stored should be first deleted (note that all database's data will be lost). + +To this end, after the image build process, the following commands should be executed: .. code-block:: console - docker stop ; docker rm ; sudo rm -rf /var/lib/mariadb + sudo rm -rf /var/lib/mariadb + cd validation/docker/mariadb + ./deploy.sh TAG_PRE=dev-mariadb MARIADB_ROOT_PASSWORD= UI_ADMIN_PASSWORD= UI_AKRAINO_PASSWORD= + mysql -p -uroot -h < ../../ui/db-scripts/examples/initialize_db_example.sql In the context of the full control loop mode, the following tables must be initialized with appropriate data: @@ -137,7 +161,7 @@ In the context of the full control loop mode, the following tables must be initi - blueprint (here every blueprint owner should register the name of the blueprint) - blueprint_instance_for_validation (here every blueprint owner should register the blueprint instances for validation, i.e. version, layer and description of a layer) -The following file can be used for initializing the aforementioned data (as we did in the above example using the 'mysql -p -uroot -h < ../../ui/db-scripts/examples/initialize_db_example.sql' command): +The following file can be used for initializing the aforementioned data (as it was performed in the above example using the 'mysql -p -uroot -h < ../../ui/db-scripts/examples/initialize_db_example.sql' command): db-scripts/examples/initialize_db_example.sql @@ -305,21 +329,21 @@ The pom.xml file supports the building of an appropriate container image using t This script accepts the following as input parameters: -CONTAINER_NAME, name of the contaner, default value is akraino-validation-ui +CONTAINER_NAME, the name of the contaner, default value is akraino-validation-ui DB_CONNECTION_URL, the URL connection with the akraino database of the maridb instance, this variable is required -MARIADB_ROOT_PASSWORD, mariadb root user password, this variable is required -REGISTRY, registry of the mariadb image, default value is akraino -NAME, name of the mariadb image, default value is validation -TAG_PRE, first part of the image version, default value is ui -TAG_VER, last part of the image version, default value is latest +MARIADB_ROOT_PASSWORD, the mariadb root user password, this variable is required +REGISTRY, the registry of the mariadb image, default value is akraino +NAME, the name of the mariadb image, default value is validation +TAG_PRE, the first part of the image version, default value is ui +TAG_VER, the last part of the image version, default value is latest JENKINS_URL, the URL of the Jenkins instance, this variable is required JENKINS_USERNAME, the Jenkins user name, this variable is required JENKINS_USER_PASSWORD, the Jenkins user password, this variable is required JENKINS_JOB_NAME, the name of Jenkins job capable of executing the blueprint validation tests, this variable is required -NEXUS_PROXY, the proxy needed in order for the Nexus server to be reachable, default value is none -JENKINS_PROXY, the proxy needed in order for the Jenkins server to be reachable, default value is none +NEXUS_PROXY, the needed proxy in order for the Nexus server to be reachable, default value is none +JENKINS_PROXY, the needed proxy in order for the Jenkins server to be reachable, default value is none -Let's build the image using only the required parameters. To this end, the following data is needed: +In order to build the image using only the required parameters, the following data is needed: - The mariadb root user password (look at the Database subsection) - The URL for connecting to the akraino database of the mariadb @@ -327,12 +351,12 @@ Let's build the image using only the required parameters. To this end, the follo - The Jenkins username and password - The name of Jenkins Job -Execute the following commands in order to build and deploy the UI container: +Then, the following commands can be executed in order to build and deploy the UI container: .. code-block:: console cd validation/ui - mvn docker:build + mvn docker:build -Ddocker.filter=akraino/validation:dev-ui-latest cd ../docker/ui ./deploy.sh TAG_PRE=dev-ui DB_CONNECTION_URL= MARIADB_ROOT_PASSWORD= JENKINS_URL= JENKINS_USERNAME= JENKINS_USER_PASSWORD= JENKINS_JOB_NAME= @@ -340,7 +364,7 @@ The content of the DB_CONNECTION_URL can be for example 172.17.0.3:3306/akraino Furthermore, the TAG_PRE variable should be defined as the default value is 'ui' (note that the 'dev-ui' is used for development purposes - look at pom.xml file). -If no proxy exists, just do not define proxy ip and port variables. +If no proxy exists, the proxy ip and port variables should not be defined. The UI should be available in the following url: diff --git a/ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql b/ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql index 611c6f8..bf18eab 100644 --- a/ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql +++ b/ui/db-scripts/EcompSdkDMLMySql_2_4_Common.sql @@ -168,6 +168,7 @@ INSERT INTO fn_restricted_url VALUES('report/wizard/retrieve_data/true','menu_re -- fn_role Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (16,'Standard User','Y',5); Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (1,'System Administrator','Y',1); +Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (17,'Blueprint Validation UI user','Y',5); -- fn_role_composite Insert into fn_role_composite (PARENT_ROLE_ID,CHILD_ROLE_ID) values (1,16); @@ -202,6 +203,9 @@ Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_map'); Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_profile'); Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_reports'); Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_tab'); +Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (17,'menu_home'); +Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (17,'menu_tab'); + -- fn_tab Insert into fn_tab (TAB_CD,TAB_NAME,TAB_DESCR,ACTION,FUNCTION_CD,ACTIVE_YN,SORT_ORDER,PARENT_TAB_CD,TAB_SET_CD) values ('TAB2_SUB1_S1','Left Tab 1','Sub - Sub Tab 1 Information','tab2_sub1.htm','menu_tab','Y',10,'TAB2_SUB1','APP'); diff --git a/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql b/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql index 781e8bc..c248b5b 100644 --- a/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql +++ b/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql @@ -26,14 +26,28 @@ INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (930, 'Search', 9, 15, 'userProfile', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/search_profile.png'); INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (150022, 'Menus', 10, 60, 'admin#/admin_menu_edit', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL); INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (150038,'Notebook',5000,135,'samplePage#/notebook','menu_sample','Y',NULL,NULL,NULL,NULL,'APP','N',NULL); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (21, 'New Submission', 1, 10, 'newSubmission', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-building-home'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (22, 'Committed Submissions', 1, 10, 'committedSubmissions', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-building-home'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (23, 'Validation Results', 1, 10, 'report.htm', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-misc-piechart'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (24, 'Get by submission id', 23, 10, 'getBySubmissionId', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (25, 'Get by blueprint name', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (26, 'Get by layer', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (27, 'Get by execution dates', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (28, 'Get by number of successful runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (29, 'Get by number of successful last runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (30, 'Get by number of failed last runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); +Insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (31, 'Get all', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); + -- fn_user Insert into fn_user (USER_ID,ORG_ID,MANAGER_ID,FIRST_NAME,MIDDLE_NAME,LAST_NAME,PHONE,FAX,CELLULAR,EMAIL,ADDRESS_ID,ALERT_METHOD_CD,HRID,ORG_USER_ID,ORG_CODE,LOGIN_ID,LOGIN_PWD,LAST_LOGIN_DATE,ACTIVE_YN,CREATED_ID,CREATED_DATE,MODIFIED_ID,MODIFIED_DATE,IS_INTERNAL_YN,ADDRESS_LINE_1,ADDRESS_LINE_2,CITY,STATE_CD,ZIP_CODE,COUNTRY_CD,LOCATION_CLLI,ORG_MANAGER_USERID,COMPANY,DEPARTMENT_NAME,JOB_TITLE,TIMEZONE,DEPARTMENT,BUSINESS_UNIT,BUSINESS_UNIT_NAME,COST_CENTER,FIN_LOC_CODE,SILO_STATUS) values (1,null,null,'admin',null,'User',null,null,null,'admin@email.com',null,null,null,'admin',null,'admin','admin_password',str_to_date('24-OCT-16','%d-%M-%Y'),'Y',null,str_to_date('17-OCT-16','%d-%M-%Y'),1,str_to_date('24-OCT-16','%d-%M-%Y'),'N',null,null,null,'NJ',null,'US',null,null,null,null,null,10,null,null,null,null,null,null); +Insert into fn_user (USER_ID,ORG_ID,MANAGER_ID,FIRST_NAME,MIDDLE_NAME,LAST_NAME,PHONE,FAX,CELLULAR,EMAIL,ADDRESS_ID,ALERT_METHOD_CD,HRID,ORG_USER_ID,ORG_CODE,LOGIN_ID,LOGIN_PWD,LAST_LOGIN_DATE,ACTIVE_YN,CREATED_ID,CREATED_DATE,MODIFIED_ID,MODIFIED_DATE,IS_INTERNAL_YN,ADDRESS_LINE_1,ADDRESS_LINE_2,CITY,STATE_CD,ZIP_CODE,COUNTRY_CD,LOCATION_CLLI,ORG_MANAGER_USERID,COMPANY,DEPARTMENT_NAME,JOB_TITLE,TIMEZONE,DEPARTMENT,BUSINESS_UNIT,BUSINESS_UNIT_NAME,COST_CENTER,FIN_LOC_CODE,SILO_STATUS) values (2,null,null,'akraino',null,'User',null,null,null,'akraino@email.com',null,null,null,'akraino',null,'akraino','akraino_password',str_to_date('24-OCT-16','%d-%M-%Y'),'Y',null,str_to_date('17-OCT-16','%d-%M-%Y'),1,str_to_date('24-OCT-16','%d-%M-%Y'),'N',null,null,null,'NJ',null,'US',null,null,null,null,null,10,null,null,null,null,null,null); -- fn_app Insert into fn_app (APP_ID,APP_NAME,APP_IMAGE_URL,APP_DESCRIPTION,APP_NOTES,APP_URL,APP_ALTERNATE_URL,APP_REST_ENDPOINT,ML_APP_NAME,ML_APP_ADMIN_ID,MOTS_ID,APP_PASSWORD,OPEN,ENABLED,THUMBNAIL,APP_USERNAME,UEB_KEY,UEB_SECRET,UEB_TOPIC_NAME) VALUES (1,'Default',null,'Some Default Description','Some Default Note',null,null,null,'ECPP','?','1','JuCerIRKt/faEcx8QdgncLEEv+IOZjpHe7Pi5DEPqKs=','N','N',null,'Default',null,null,'ECOMP-PORTAL-INBOX'); -- fn_user_role Insert into fn_user_role (USER_ID,ROLE_ID,PRIORITY,APP_ID) values (1,1,null,1); +Insert into fn_user_role (USER_ID,ROLE_ID,PRIORITY,APP_ID) values (2,17,null,1); commit; diff --git a/ui/db-scripts/akraino-blueprint_validation_db.sql b/ui/db-scripts/akraino-blueprint_validation_db.sql deleted file mode 100644 index c2d7320..0000000 --- a/ui/db-scripts/akraino-blueprint_validation_db.sql +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -SET FOREIGN_KEY_CHECKS=1; - -use akraino; - -DROP TABLE IF EXISTS submission; -DROP TABLE IF EXISTS blueprint_instance_for_validation; -DROP TABLE IF EXISTS blueprint; -DROP TABLE IF EXISTS silo; -DROP TABLE IF EXISTS timeslot; -DROP TABLE IF EXISTS lab; - -create table lab ( - id bigint not NULL AUTO_INCREMENT, - lab text not NULL, - CONSTRAINT id_pk PRIMARY KEY (id) -); - -create table timeslot ( - id bigint not NULL AUTO_INCREMENT, - start_date_time text, - duration text, - lab_id bigint not NULL, - CONSTRAINT id_pk PRIMARY KEY (id), - CONSTRAINT lab_id_fk FOREIGN KEY (lab_id) - REFERENCES lab (id) MATCH SIMPLE - ON UPDATE NO ACTION ON DELETE NO ACTION -); - -create table silo ( - id bigint not NULL AUTO_INCREMENT, - silo text not NULL, - lab_id bigint not NULL, - CONSTRAINT id_pk PRIMARY KEY (id), - CONSTRAINT lab_id_fk2 FOREIGN KEY (lab_id) - REFERENCES lab (id) MATCH SIMPLE - ON UPDATE NO ACTION ON DELETE NO ACTION -); - -CREATE TABLE blueprint -( - id bigint not NULL AUTO_INCREMENT, - blueprint_name varchar(20) not NULL unique, - CONSTRAINT id_pk PRIMARY KEY (id) -); - -CREATE TABLE blueprint_instance_for_validation -( - id bigint not NULL AUTO_INCREMENT, - blueprint_id bigint not NULL, - version text not NULL, - layer text not NULL, - layer_description text not NULL, - CONSTRAINT id_pk PRIMARY KEY (id), - CONSTRAINT blueprint_id_fk FOREIGN KEY (blueprint_id) - REFERENCES blueprint (id) MATCH SIMPLE - ON UPDATE NO ACTION ON DELETE NO ACTION -); - -CREATE TABLE submission -( - id bigint not NULL AUTO_INCREMENT, - status text not NULL, - jenkins_queue_job_item_url text, - nexus_result_url text, - blueprint_instance_for_validation_id bigint not NULL, - timeslot_id bigint not NULL, - CONSTRAINT id_pk PRIMARY KEY (id), - CONSTRAINT blueprint_instance_for_validation_id_fk FOREIGN KEY (blueprint_instance_for_validation_id) - REFERENCES blueprint_instance_for_validation (id) MATCH SIMPLE - ON UPDATE NO ACTION ON DELETE NO ACTION, - CONSTRAINT timeslot_id_fk FOREIGN KEY (timeslot_id) - REFERENCES timeslot (id) MATCH SIMPLE - ON UPDATE NO ACTION ON DELETE NO ACTION -); - -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (21, 'New Submission', 1, 10, 'newSubmission', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-building-home'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (22, 'Committed Submissions', 1, 10, 'committedSubmissions', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-building-home'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (23, 'Validation Results', 1, 10, 'report.htm', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-misc-piechart'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (24, 'Get by submission id', 23, 10, 'getBySubmissionId', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (25, 'Get by blueprint name', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (26, 'Get by layer', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (27, 'Get by execution dates', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (28, 'Get by number of successful runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (29, 'Get by number of successful last runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (30, 'Get by number of failed last runs', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); -insert into fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC) VALUES (31, 'Get all', 23, 10, '', 'menu_tab', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', '/static/fusion/images/reports.png'); - --- fn_user -Insert into fn_user (USER_ID,ORG_ID,MANAGER_ID,FIRST_NAME,MIDDLE_NAME,LAST_NAME,PHONE,FAX,CELLULAR,EMAIL,ADDRESS_ID,ALERT_METHOD_CD,HRID,ORG_USER_ID,ORG_CODE,LOGIN_ID,LOGIN_PWD,LAST_LOGIN_DATE,ACTIVE_YN,CREATED_ID,CREATED_DATE,MODIFIED_ID,MODIFIED_DATE,IS_INTERNAL_YN,ADDRESS_LINE_1,ADDRESS_LINE_2,CITY,STATE_CD,ZIP_CODE,COUNTRY_CD,LOCATION_CLLI,ORG_MANAGER_USERID,COMPANY,DEPARTMENT_NAME,JOB_TITLE,TIMEZONE,DEPARTMENT,BUSINESS_UNIT,BUSINESS_UNIT_NAME,COST_CENTER,FIN_LOC_CODE,SILO_STATUS) values (2,null,null,'akraino',null,null,null,null,null,null,null,null,null,'akraino',null,'akraino','akraino_password',now(),'Y',null,now(),1,now(),'N',null,null,null,'NJ',null,'US',null,null,null,null,null,10,null,null,null,null,null,null); - --- fn_role -Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (17,'Blueprint Validation UI user','Y',5); - --- fn_role_function -Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (17,'menu_home'); -Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (17,'menu_tab'); - --- fn_user_role -Insert into fn_user_role (USER_ID,ROLE_ID,PRIORITY,APP_ID) values (2,17,null,1); - -commit; diff --git a/ui/db-scripts/akraino_blueprint_validation_db.sql b/ui/db-scripts/akraino_blueprint_validation_db.sql new file mode 100644 index 0000000..06aa4a8 --- /dev/null +++ b/ui/db-scripts/akraino_blueprint_validation_db.sql @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +SET FOREIGN_KEY_CHECKS=1; + +use akraino; + +DROP TABLE IF EXISTS submission; +DROP TABLE IF EXISTS blueprint_instance_for_validation; +DROP TABLE IF EXISTS blueprint; +DROP TABLE IF EXISTS silo; +DROP TABLE IF EXISTS timeslot; +DROP TABLE IF EXISTS lab; + +create table lab ( + id bigint not NULL AUTO_INCREMENT, + lab text not NULL, + CONSTRAINT id_pk PRIMARY KEY (id) +); + +create table timeslot ( + id bigint not NULL AUTO_INCREMENT, + start_date_time text, + duration text, + lab_id bigint not NULL, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT lab_id_fk FOREIGN KEY (lab_id) + REFERENCES lab (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); + +create table silo ( + id bigint not NULL AUTO_INCREMENT, + silo text not NULL, + lab_id bigint not NULL, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT lab_id_fk2 FOREIGN KEY (lab_id) + REFERENCES lab (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); + +CREATE TABLE blueprint +( + id bigint not NULL AUTO_INCREMENT, + blueprint_name varchar(20) not NULL unique, + CONSTRAINT id_pk PRIMARY KEY (id) +); + +CREATE TABLE blueprint_instance_for_validation +( + id bigint not NULL AUTO_INCREMENT, + blueprint_id bigint not NULL, + version text not NULL, + layer text not NULL, + layer_description text not NULL, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT blueprint_id_fk FOREIGN KEY (blueprint_id) + REFERENCES blueprint (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); + +CREATE TABLE submission +( + id bigint not NULL AUTO_INCREMENT, + status text not NULL, + jenkins_queue_job_item_url text, + nexus_result_url text, + blueprint_instance_for_validation_id bigint not NULL, + timeslot_id bigint not NULL, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT blueprint_instance_for_validation_id_fk FOREIGN KEY (blueprint_instance_for_validation_id) + REFERENCES blueprint_instance_for_validation (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT timeslot_id_fk FOREIGN KEY (timeslot_id) + REFERENCES timeslot (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); + +commit; diff --git a/ui/pom.xml b/ui/pom.xml index 46c647f..e4736ef 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -35,7 +35,7 @@ 2.0.2 2.8 1.0.0 - 2.8.10 + 2.9.9 0.9.5.2 2.0.0 3.1.0 @@ -144,6 +144,7 @@ + io.fabric8 docker-maven-plugin @@ -175,7 +176,7 @@ - + diff --git a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/CrumbResponse.java b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/CrumbResponse.java index 5cf4518..f7a4eb8 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/CrumbResponse.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/CrumbResponse.java @@ -1,17 +1,17 @@ /* * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. */ package org.akraino.validation.ui.client.jenkins.resources; @@ -24,7 +24,7 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; public class CrumbResponse implements IResource { @JsonProperty("_class") - private String classCrumb; + private String _class; @JsonProperty("crumb") private String crumb; @@ -36,12 +36,12 @@ public class CrumbResponse implements IResource { } - public String getClassCrumb() { - return this.classCrumb; + public String get_class() { + return this._class; } - public void setClassCrumb(String classCrumb) { - this.classCrumb = classCrumb; + public void set_class(String _class) { + this._class = _class; } public String getCrumb() { diff --git a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/QueueJobItem.java b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/QueueJobItem.java index 9da3891..c5fdd77 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/QueueJobItem.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/resources/QueueJobItem.java @@ -1,17 +1,17 @@ /* * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. */ package org.akraino.validation.ui.client.jenkins.resources; @@ -26,7 +26,7 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; public class QueueJobItem implements IResource { @JsonProperty("_class") - private String classQueue; + private String _class; @JsonProperty("executable") private Executable executable; @@ -35,12 +35,12 @@ public class QueueJobItem implements IResource { } - public String getClassQueue() { - return this.classQueue; + public String get_class() { + return this._class; } - public void setClassQueue(String classQueue) { - this.classQueue = classQueue; + public void set_class(String _class) { + this._class = _class; } public Executable getExecutable() { @@ -53,7 +53,7 @@ public class QueueJobItem implements IResource { public class Executable { @JsonProperty("_class") - private String classQueue; + private String _class; @JsonProperty("number") private Integer number; @@ -61,12 +61,12 @@ public class QueueJobItem implements IResource { @JsonProperty("url") private URL url; - public String getClassQueue() { - return this.classQueue; + public String get_class() { + return this._class; } - public void setClassQueue(String classQueue) { - this.classQueue = classQueue; + public void set_class(String _class) { + this._class = _class; } public Integer getNumber() { diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/NexusExecutorClient.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/NexusExecutorClient.java index a0723c8..7ee7239 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/nexus/NexusExecutorClient.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/NexusExecutorClient.java @@ -45,6 +45,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; @@ -178,6 +179,8 @@ public final class NexusExecutorClient { JSONObject xmlJSONObj = XML.toJSONObject(result); ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + mapper.setSerializationInclusion(Include.NON_NULL); RobotTestResult robotTestResult = mapper.readValue(xmlJSONObj.toString(), RobotTestResult.class); robotTestResult.setName(testSuiteName); robotTestResults.add(robotTestResult); diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Kw.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Kw.java new file mode 100644 index 0000000..d078bec --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Kw.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package org.akraino.validation.ui.client.nexus.resources; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public class Kw { + @JsonProperty("name") + private String name; + + @JsonProperty("type") + private String type; + + @JsonProperty("library") + private String library; + + @JsonProperty("doc") + private String doc; + + @JsonProperty("status") + private Kw.Status status; + + @JsonProperty("kw") + private List kw; + + public Kw() { + + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLibrary() { + return this.library; + } + + public void setLibrary(String library) { + this.library = library; + } + + public String getDoc() { + return this.doc; + } + + public void setDoc(String doc) { + this.doc = doc; + } + + public Kw.Status getStatus() { + return this.status; + } + + public void setStatus(Kw.Status status) { + this.status = status; + } + + public List getKw() { + return this.kw; + } + + public void setKw(List kw) { + this.kw = kw; + } + + public class Status { + @JsonProperty("endtime") + private String endtime; + + @JsonProperty("starttime") + private String starttime; + + @JsonProperty("status") + private String status; + + public Status() { + + } + + public String getEndtime() { + return this.endtime; + } + + public void setEndtime(String endtime) { + this.endtime = endtime; + } + + public String getStarttime() { + return this.starttime; + } + + public void setStarttime(String starttime) { + this.starttime = starttime; + } + + public String getStatus() { + return this.status; + } + + public void setStatus(String status) { + this.status = status; + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/RobotTestResult.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/RobotTestResult.java index 44ddc56..b604438 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/RobotTestResult.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/RobotTestResult.java @@ -114,22 +114,28 @@ public class RobotTestResult implements IResource { @JsonProperty("status") private Suite.Status status; - @JsonProperty("_id") - private String suiteId; + @JsonProperty("suite") + private Suite.NestedSuite suite; + + @JsonProperty("id") + private String id; - @JsonProperty("_name") + @JsonProperty("name") private String name; + @JsonProperty("source") + private String source; + public Suite() { } - public String getSuiteId() { - return this.suiteId; + public String getId() { + return this.id; } - public void setSuiteId(String suiteId) { - this.suiteId = suiteId; + public void setId(String id) { + this.id = id; } public String getName() { @@ -140,6 +146,14 @@ public class RobotTestResult implements IResource { this.name = name; } + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + public Suite.Status getStatus() { return this.status; } @@ -148,45 +162,175 @@ public class RobotTestResult implements IResource { this.status = status; } + public Suite.NestedSuite getSuite() { + return this.suite; + } + + public void setSuite(Suite.NestedSuite suite) { + this.suite = suite; + } + public class Status { - @JsonProperty("_status") - private String statusValue; + @JsonProperty("status") + private String status; - @JsonProperty("_starttime") - private String startTime; + @JsonProperty("starttime") + private String starttime; - @JsonProperty("_endtime") - private String endTime; + @JsonProperty("endtime") + private String endtime; public Status() { } - public String getStatusValue() { - return this.statusValue; + public String getStatus() { + return this.status; } - public void setStatusValue(String statusValue) { - this.statusValue = statusValue; + public void setStatus(String status) { + this.status = status; } - public String getStartTime() { - return this.startTime; + public String getStarttime() { + return this.starttime; } - public void setStartTime(String startTime) { - this.startTime = startTime; + public void setStarttime(String starttime) { + this.starttime = starttime; } - public String getEndTime() { - return this.endTime; + public String getEndtime() { + return this.endtime; } - public void setEndTime(String endTime) { - this.endTime = endTime; + public void setEndtime(String endtime) { + this.endtime = endtime; } } + public class NestedSuite { + @JsonProperty("doc") + private String doc; + + @JsonProperty("id") + private String id; + + @JsonProperty("name") + private String name; + + @JsonProperty("source") + private String source; + + @JsonProperty("test") + private List test; + + @JsonProperty("kw") + private List kw; + + @JsonProperty("status") + private NestedSuite.Status status; + + public NestedSuite() { + + } + + public String getDoc() { + return this.doc; + } + + public void setDoc(String doc) { + this.doc = doc; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public List getTest() { + return this.test; + } + + public void setTest(List test) { + this.test = test; + } + + public List getKw() { + return this.kw; + } + + public void setKw(List kw) { + this.kw = kw; + } + + public NestedSuite.Status getStatus() { + return this.status; + } + + public void setStatus(NestedSuite.Status status) { + this.status = status; + } + + public class Status { + @JsonProperty("status") + private String status; + + @JsonProperty("starttime") + private String starttime; + + @JsonProperty("endtime") + private String endtime; + + public Status() { + + } + + public String getStatus() { + return this.status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStarttime() { + return this.starttime; + } + + public void setStarttime(String starttime) { + this.starttime = starttime; + } + + public String getEndtime() { + return this.endtime; + } + + public void setEndtime(String endtime) { + this.endtime = endtime; + } + + } + } } public class Statistics { diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Test.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Test.java new file mode 100644 index 0000000..7a9f0c5 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/Test.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package org.akraino.validation.ui.client.nexus.resources; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public class Test { + @JsonProperty("doc") + private String doc; + + @JsonProperty("id") + private String id; + + @JsonProperty("name") + private String name; + + @JsonProperty("status") + private Test.Status status; + + @JsonProperty("kw") + private List kw; + + public Test() { + + } + + public String getDoc() { + return this.doc; + } + + public void setDoc(String doc) { + this.doc = doc; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Test.Status getStatus() { + return this.status; + } + + public void setStatus(Test.Status status) { + this.status = status; + } + + public List getKw() { + return this.kw; + } + + public void setKw(List kw) { + this.kw = kw; + } + + public class Status { + @JsonProperty("status") + private String status; + + @JsonProperty("starttime") + private String starttime; + + @JsonProperty("endtime") + private String endtime; + + @JsonProperty("critical") + private String critical; + + @JsonProperty("content") + private String content; + + public Status() { + + } + + public String getStatus() { + return this.status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStarttime() { + return this.starttime; + } + + public void setStarttime(String starttime) { + this.starttime = starttime; + } + + public String getEndtime() { + return this.endtime; + } + + public void setEndtime(String endtime) { + this.endtime = endtime; + } + + public String getCritical() { + return this.critical; + } + + public void setCritical(String critical) { + this.critical = critical; + } + + public String getContent() { + return this.content; + } + + public void setContent(String content) { + this.content = content; + } + } +} diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/SubmissionController.java b/ui/src/main/java/org/akraino/validation/ui/controller/SubmissionController.java index bb898a9..fb6f8e0 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/SubmissionController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/SubmissionController.java @@ -63,16 +63,4 @@ public class SubmissionController extends RestrictedBaseController { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } - @RequestMapping(value = {"/"}, method = RequestMethod.DELETE) - public ResponseEntity deleteSubmission(@RequestBody Submission submission) { - try { - service.deleteSubmission(submission.getSubmissionId()); - return new ResponseEntity<>(true, HttpStatus.OK); - } catch (Exception e) { - LOGGER.error(EELFLoggerDelegate.errorLogger, - "Deletion of submission failed. " + UserUtils.getStackTrace(e)); - } - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); - } - } diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js index 538793e..27d4a14 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js +++ b/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js @@ -19,8 +19,6 @@ var app = angular.module('AECCommittedSubmissions'); app.controller('AECCommittedSubmissionsController', function($scope, restAPISvc, $interval, refreshPeriod) { - $scope.submissionIdList = []; - restAPISvc.getRestAPI("/api/submission/", function(data) { $scope.submissions = data; }); @@ -31,27 +29,6 @@ app.controller('AECCommittedSubmissionsController', function($scope, }); } - $scope.modifySubmissionIdList = function(id) { - if ($scope.submissionIdList.indexOf(id) === -1) { - $scope.submissionIdList.push(id); - } else { - $scope.submissionIdList.splice($scope.submissionIdList.indexOf(id), - 1); - } - } - - $scope.deleteSubmissions = function() { - var confirmation = confirm("Are you sure?"); - if (confirmation == true) { - angular.forEach($scope.submissionIdList, function(id) { - var submission = { - "submissionId" : id - }; - restAPISvc.deleteRestAPI("/api/submission/", submission); - }); - } - } - $interval(function() { $scope.refreshCommittedSubmissions(); }, refreshPeriod); diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html b/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html index 784810b..b2e3838 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html +++ b/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html @@ -47,34 +47,25 @@ body { Id:
-
- +
- -
- -
-
@@ -231,12 +222,61 @@ body { min-width: 118px; max-width: 118px; } + +.table-container { + display: inline-block; + height: 400px; + padding-top: 1.875em; + position: relative; +} + +.table-container>div { + border-color: #888; + border-style: solid; + border-width: 1px 1px 2px 1px; + height: 1.7em; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +table { + display: block; + height: 400px; + overflow-y: auto; +} + +th { + padding: 0 5px; + text-align: center; +} + +th:first-child>div { + border-left: none; + padding-left: 7px; +} + +th>div { + border-left: 2px solid #888; + line-height: 1.875em; + margin-left: -6px; + padding-left: 5px; + position: absolute; + top: 0; +} + +td { + border-color: #888; + border-style: solid; + border-width: 0 1px 2px 1px; + padding: 5px; +} -
- +
+
- @@ -247,12 +287,8 @@ body { - - +
  Id  Status  Blueprint 
{{ submission.submissionId }} {{ @@ -278,20 +314,6 @@ body {
-
-
- -
- -
-
diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js index d53bcc7..ebad5be 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js +++ b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js @@ -23,6 +23,8 @@ app initialize(); function initialize() { + $scope.loading = false; + $scope.showResults = false; $scope.results = []; $scope.resultsLayers = []; $scope.resultsLayerTestSuitesNames = []; @@ -38,24 +40,27 @@ app $scope.submissions, function( submissionData) { - var temp = "id: " - + submissionData.submissionId - + " blueprint: " - + submissionData.blueprintInstanceForValidation.blueprint.blueprintName - + " version: " - + submissionData.blueprintInstanceForValidation.version - + " layer: " - + submissionData.blueprintInstanceForValidation.layer - + " lab: " - + submissionData.timeslot.lab.lab - + " Start date and time: " - + submissionData.timeslot.startDateTime - /* - * + " duration: " + - * submissionData.blueprintInstanceForValidation.timeslot.duration - */; - $scope.submissionsForDisplay - .push(temp); + if (submissionData.submissionStatus === "Completed") { + var temp = "id: " + + submissionData.submissionId + + " blueprint: " + + submissionData.blueprintInstanceForValidation.blueprint.blueprintName + + " version: " + + submissionData.blueprintInstanceForValidation.version + + " layer: " + + submissionData.blueprintInstanceForValidation.layer + + " lab: " + + submissionData.timeslot.lab.lab + + " Start date and time: " + + submissionData.timeslot.startDateTime + /* + * + " + * duration: " + + * submissionData.blueprintInstanceForValidation.timeslot.duration + */; + $scope.submissionsForDisplay + .push(temp); + } }); }); } @@ -65,6 +70,8 @@ app $scope.resultsLayers = []; $scope.resultsLayerTestSuitesNames = []; $scope.selectedRobotTestResult = []; + $scope.loading = true; + $scope.showResults = false; var id = selectedSubmission.substring( selectedSubmission.indexOf("id:") + 4, selectedSubmission.indexOf("blueprint") - 1); @@ -72,6 +79,7 @@ app .getRestAPI( "/api/results/getBySubmissionId/" + id, function(data) { + $scope.loading = false; if (data !== undefined) { $scope.results = data; angular @@ -81,6 +89,7 @@ app $scope.resultsLayers .push(result.blueprintLayer); }); + $scope.showResults = true; } else { confirm("Error when committing the submission"); } diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html index 3e86330..8d6324c 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html +++ b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html @@ -32,175 +32,357 @@ limitations under the License. float: left; height: 100%; } + +div.box { + border: 1px solid black; +}

Get results by submission

+

General matching string:

+
+ +
+

Select Submission:

-

Select a blueprint layer of the selected - submission:

-
- +
+
-

Select a test suite of the selected - (submission, layer) pair in order to be displayed:

-
- -
+

+
+

Select a blueprint layer of the + selected submission:

+
+ +
+

Select a test suite of the selected + (submission, layer) pair in order to be displayed:

+
+ +
+



-
+
+
+

+
+

+ General Info +

+

-

- Test info -

- -

-

Name: {{selectedRobotTestResult.name}}

-

Generated: {{selectedRobotTestResult.robot.generated}}

-

Generator: {{selectedRobotTestResult.robot.generator}}

-

Errors: {{selectedRobotTestResult.robot.errors}}

- -

-

- Test Statistics -

-

- - - - - - - - - - - - - - - - - - - -
-

-

 Total statistics 

Total 

Pass 

Fail 

Pass / Fail 

{{ - stat.content }}{{ - (stat.fail * 1) + (stat.pass*1) }}{{ - stat.pass }}{{ - stat.fail}} -
-
-
-
-
- -
- -

- - - - - - - - - - - - - - - - - - - -
-

-

 Statistics by Tag 

Total 

Pass 

Fail 

Pass / Fail 

{{ - stat.content }}{{ - (stat.fail * 1) + (stat.pass*1) }}{{ - stat.pass }}{{ - stat.fail}} -
-
-
-
-
- -
- -

- - - - - - - - - - - - - - - - - - - -
-

-

 Statistics by Suite 

Total 

Pass 

Fail 

Pass / Fail 

{{ - stat.content }}{{ - (stat.fail * 1) + (stat.pass*1) }}{{ - stat.pass }}{{ - stat.fail}} -
-
-
+

+

Name: {{selectedRobotTestResult.name}}

+

Generated: {{selectedRobotTestResult.robot.generated}}

+

Generator: {{selectedRobotTestResult.robot.generator}}

+

Errors: {{selectedRobotTestResult.robot.errors}}

+ +

+

+ Test Statistics +

+

+ + + + + + + + + + + + + + + + + + + +
+

+

 Total statistics 

Total 

Pass 

Fail 

Pass / Fail 

{{ + stat.content }}{{ + (stat.fail * 1) + (stat.pass*1) }}{{ + stat.pass }}{{ + stat.fail}} +
+
+
+
+
+ +
+ +

+ + + + + + + + + + + + + + + + + + + +
+

+

 Statistics by Tag 

Total 

Pass 

Fail 

Pass / Fail 

{{ + stat.content }}{{ + (stat.fail * 1) + (stat.pass*1) }}{{ + stat.pass }}{{ + stat.fail}} +
+
+
+
+
+ +
+ +

+ + + + + + + + + + + + + + + + + + + +
+

+

 Statistics by Suite 

Total 

Pass 

Fail 

Pass / Fail 

{{ + stat.content }}{{ + (stat.fail * 1) + (stat.pass*1) }}{{ + stat.pass }}{{ + stat.fail}} +
+
+
+
+
+
+ +

+
+

+ Test + Execution Log +

+
+

+

Root Suite Full Name: + {{selectedRobotTestResult.robot.suite.name}}

+

Source: {{selectedRobotTestResult.robot.suite.source}}

+

Status: + {{selectedRobotTestResult.robot.suite.status.status}}

+

Start time: + {{selectedRobotTestResult.robot.suite.status.starttime}}

+

End time: + {{selectedRobotTestResult.robot.suite.status.endtime}}

+ +

+

+

Sub-suite Full Name: + {{selectedRobotTestResult.robot.suite.suite.name}}

+

Documentation: + {{selectedRobotTestResult.robot.suite.suite.doc}}

+

Source: {{selectedRobotTestResult.robot.suite.suite.source}}

+

Status: + {{selectedRobotTestResult.robot.suite.suite.status.status}}

+

Start time: + {{selectedRobotTestResult.robot.suite.suite.status.starttime}}

+

End time: + {{selectedRobotTestResult.robot.suite.suite.status.endtime}}

+
+
+ +

+
+
    +

    Sub-suite Robot keywords

    +
  • +

    +

    + + {{kw.name}} +

    +
    +

         Type: {{kw.type}}

    +

         Library: {{kw.library}}

    +

         Documentation: {{kw.doc}}

    +

         Start time: + {{kw.status.starttime}}

    +

         End time: {{kw.status.endtime}}

    +

         Status: {{kw.status.status}}

    +

    +

         Used Robot keywords

    +
      +
    • +

      +      + {{kw2.name}} +

      +
      +

               Type: + {{kw2.type}}

      +

               + Library: {{kw2.library}}

      +

               + Documentation: {{kw2.doc}}

      +

               Start + time: {{kw2.status.starttime}}

      +

               End + time: {{kw2.status.endtime}}

      +

               + Status: {{kw2.status.status}}

      +
      +
    • +
    -
+ + +
+ +

+
+

Test Cases

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+

 Full Name 

Documentation 

Status 

Start Time 

End Time 

Critical 

Message 

Robot keywords 

{{ + test.name }}{{test.doc}}{{test.status.status}}{{test.status.starttime}}{{test.status.endtime}}{{test.status.critical}}{{test.status.content}} + +
    +
  • +

    +

    + + {{testKw.name}} +

    +
    +

         Type: {{testKw.type}}

    +

         Library: {{testKw.library}}

    +

         Documentation: {{testKw.doc}}

    +

         Start time: + {{testKw.status.starttime}}

    +

         End time: + {{testKw.status.endtime}}

    +

         Status: + {{testKw.status.status}}

    +

    +

         Used Robot keywords

    +
      +
    • +

      +      + {{testKw2.name}} +

      +
      +

               + Type: {{testKw2.type}}

      +

               + Library: {{testKw2.library}}

      +

               + Documentation: {{testKw2.doc}}

      +

               + Start time: {{testKw2.status.starttime}}

      +

               + End time: {{testKw2.status.endtime}}

      +

               + Status: {{testKw2.status.status}}

      +
      +
    • +
    +
+
+
\ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js index f7d0085..2135680 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js +++ b/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js @@ -94,6 +94,13 @@ app } $scope.submit = function() { + if (!$scope.selectedBlueprintName + || !$scope.selectedBlueprintVersion + || !$scope.selectedBlueprintLayer + || !$scope.selectedDeclerativeTimeslot) { + confirm("You must specify all data fields"); + return; + } var finalBlueprint; var finalTimeslot; angular @@ -134,11 +141,17 @@ app submission, function(data) { if (data !== undefined) { - confirm("Submission committed successfully"); + var confirmText = "The blueprint instance for validation has been submitted successfully. Submissionn id:" + + data.submissionId; + confirm(confirmText); } else { confirm("Error when committing the submission"); } }); + $scope.selectedBlueprintName = {}; + $scope.selectedBlueprintVersion = {}; + $scope.selectedBlueprintLayer = {}; + $scope.selectedDeclerativeTimeslot = {}; } }); diff --git a/ui/src/main/webapp/static/fusion/images/giphy.gif b/ui/src/main/webapp/static/fusion/images/giphy.gif new file mode 100644 index 0000000000000000000000000000000000000000..7a880b39992b37c4dbb53f5b28902ee5559b9166 GIT binary patch literal 8821 zcmaKxcT^K=yY^=$lLirz5JEso=tV?uTM*G5Ac0VnB1jQ1Gyz47iV%uA2?0Wn^ls>& zAfTw&6BGeO!G`D-1T26BQBhI1a(LhGd-wUib=Ep-{(IK^F>B5BT-SB~ZU;wu%MC#Q z2!Qj8z~bWKw{PD*eE9JC_3N>*vEkw2yLa#Q^z>Z0a^>vVv#qVI_4V}?6%_>q1zA~H zLZL7*G4bHRgM0Su2?+`D^YioY@NjZ+vbD9fva+(UurM|@*4EZmRaM2|Z~y=hiA3#1 z`K>I^ZFV+ptkq`bC~)ai`!~t%Kv+;rSSUR%GA4rV;JC#N(Ebjiu>c(~U3vld*S7)a zMLInvG_oq<#HpyaSGlHxF?*l$PJKxFuqc&q*`{i_eRT)=qpXe(HN`l!`n8R;#NK|N zaBaMu=VDeqINh0WC;HO!xvr$GZGU}OxO`;r!_P&8FGv=qq^60|GcvQXb8^MU^70D` zi;7E1%gQS%tBy;mYijH28ycIMPn>LNJ=NCUar#W>*>mT+E?m5H`O4L6Qd#%)8$CCB z`}%L)9=LONaOmFs2M-?&KOTAV^si^5W6#GYCSSaK^?GW0=FQu8?`J>Eef;!!{>#^I z3*UeI{QKAMMIZpCnbR2z4N$?zjVm3OEk{$$IqeeZ_2oE&txT>vS_T@EBSOXW9)3QE zU8MLp0x9fleODs{n2>=8nlQbFK7QkNx`i`E%;+?@TZu6(TX6gY!!=ATKplAq^pRbX zbJ&a+$Q=!!JlBqM-?Cc)n2DHZ+YUB+?a1r%3%2pDiTL%3=|=@dNvIJggzL`ms@M6Q z!R2~GlgaRjt6vghg`iAf{_s0z+bFLy<_^|hoaRrYLkjAq5se4JWlG161^&A21byu4E!d{iIWid^Ptm!3z zL^mm;^2ecA@N3R8*Wj=?Wwa(6ZOT8K_>F2^lmmRq4lCoWAm|Aefo1-4I}>Sc9KgCY zyYS&*b6CPa|NfQ6N6XW@?lPzbVJNhsM;sqT>sCTytwlzW)MoT1|n_Z< zJE=GsQ1Ou>S>NEHNdlho_+Gw&k+HPEbNdE;MfuR?S4F-C()YTVzKMU}M#|4$R^dl2ye02lB+Lf$tDp z%Ul28S=(mx@1)Ot^S{sB--=VX^U*1&wR7dgRmF^Pr|zfQIANG`R!TEvzNck{`?@#RD%B7Jc5B>zajuO|NEv3H*Qe_k5+=FtNJL+Cb>grcgu&x+2|Ok!N{l^75LRrje`MuhPc`NN6E>!Le)m5{+Gm!C^;NFCb4q2%L0FO=TQnr~UzfjFA+i&E zsFt9X(M1%;`*o6Slb2&UR&!+h#f{0-z6!^KGN%I$wP@xxx2MTsrbAI@!wiM7VvJ$0 z{9U5E9dT@hx$Rz%kjpWV3(0F>Jj4;^VB+Hs@>{T&rX#+c=n~Mum{L)mpbK5#TPnjs`Rzaqa-?k4pPH<+pER8@Sb{(;8-0ow# z+&X3fk=cMVTP}|X7hm$ze!kh@$)WonJEQyTa1emih(UJp)m+5Vc&2BN5)N&SV*z-d zIX)kIM8)PHyKhQ*Q#EkN`-UoHE|#S%G=Jlx3Br16ykcxquK~<#x8bX9=K@Tlm51&r zXV&FE04YS#1XhL8;GDIr?2L=e5xoK_TIEzYKhK^^auv_GJ#zJcEX5#p+@e3-=`$Uy zVHCONschT2PP;cV+p_o7mfhkR?%X z{QpGV4g4$l(jg)rfUN(WeDw;2&*seEm?GIA-!BWJ-2OTQaWf+Jy?eKVwq8LFgF*A+ zy%VFuLlAy)id~>f+F>Tl&q~i>qU`fZpiDlzz0|dmRalf?x23@jRm4Zto@}u@A;G{U zb!m?0&T+uDcA+nXDtB&U)wUjQzsQb>y~M#p?`Unx>aoMgkK_88PLFM0Z$0g02W%fK zdb5*`l_Pv5;9q>2u7}PXX!7KnyM3s-l9V#J;d@;>Lx9G-UuikiN>~nrUu6{-&1$t8 z%&%MRBW8G3W%$seJ?ZVvRUpZ*=Go~z&QOlrXGSpUOkMAy_1X)af3qo$lu&lQ&W^R8 zag_|0`N}ND*%MwTh%|MaUyMlD#|2%_GQhE$B(4?ih!uw{k-7>%xPHt3t$ z<~H0{m2po<$1mT+n$zKN06Tj~Dnlt-FzWf}<9iK-fXyBLR$Zk}AO@sT7Bn$9x&;7j z4qNTK0yIae`6N+S#-3Kh96+1Jiuus(z1m(|Z3JQ|W;T9K<3RL#hY1zMB=H31)3M3t zq6+`W+h~>_$DekP9Z{dbf`_CzbNXUO9ivm}B9dvWBph?Vs-`k%%jQNIR^5NdaHXTd zS_CEA#CR3te>P+!2=queR__-@M(QeJ-^?`TVZi^ZTrI%#A3H`bjvFp@xiVSvQkTmS zT3(I`Sf1MYA!$+WRQKTHjKgwg^4rmRRso>xtYhobyzRAL(l^DP+&St|H+tmORoe%q zYCpSo%%6OBq|I4yF&eN$V~{wLZH53h97ZRY8yld~F=#k@Rhso~14wL%$zPGFRiIa8 zni`seuBfOpOgD*x1*YzMjy9jLWY_2c=gbaUNz1w}bVyeK5Gp~q$^HC^Jm}JyvV@0g zfuV|vy=#w#6|I5pp};ZORjp}jkNfYe`{Bvw9V5&sukTTRd;c=QLUQUnx(C^J(VoDO zwpZJw%99Z%%gJh%2s7*cH}~G8AZzcsJfD${Af|SI!6N9_zgnye!Xfq<`lojpm0Pdz zjpPDT3V0&T&3Aaf5yZ3gt=-05nC^z4x*khSCR3S@Rp#` zeM^%|2O$&}WG}9pjGLQSt?AF(QXQ^6b15KcCOBY$3}B7augyss#y^d)a1req2UFl* zxF8+y`JH<&Xbh>nW^KvPPQ0AYxY|ApwdKp84mJk@k&a&vcHl{QZqEeDyxvsKBQU&5 zSJ6mh6BlK4+BQ{B9RSf3#vElc^suWNt?{x+rciDA)|An}6f*Q!bmx7xN{Y~3f0u$!76BW&O{u*PM6&C%p4^Bq!$l{%UJa=bdg?fA6lH5 zxMN3q#={5ni^I(R0lzlqJU;q{9SU$gWFI;1GismKiT=wOD1&atZ2eaBBmgyN_vx8F z`EkRjnfB|Jp+EZA&nu1wL+AF>QnPPt4z(7$@cD!ryEr~T(&$_bMo3zpXm=RTuNuz zG}wagDrGMnrc4(bqJC_0v-_rEZ)wm4%;sol-8XCw4^8SK|{~ z5rK?*Z?n70OC%NREoV8NxPXky0{5?7t;4a!DlVsb9-~)-qy*gN-Yr9)eb=GYt*3tj z;NVI|i?0KF+>9IeG#KY^`M%l?Gike;eZDh(-7md-9etPHvVK$*vP4EvsVO7|{Cei54XP72GPWGUL^Mzu z+U+(+DRbI&)rq!nI}l4$m%3|1ZbQd0^3Oh1YoZuP<(>x9A$kIt_<3>p_yH%wFKx_B`;93!;wK#&YgWr(Mhu|5kxOzvjBA>;^3 zW|roLH_eSUOVjax2H{{JWGVDF{y$yz#{Y?ZVbFwQs{nF3!AZa4*PQ%*zsVX=Cer4| zo+J0uKi_YUzG##D(JeYl;q#KB+!DgV`8$!Y43ES#kr&9NqjR}QM_E~7yIk*mIjsB& z=OdMp)VkeJ{@(0n+bU528z|2xKHU+!6)v~SV_(?aaF!W!jn|uj1o3O_fS#!1&i!^h zk894Nh8!-k!3TVB)EjlEk6$*WuO7}9hEj6u!%;KfKcrgh1| zIJcP6$LIg1t059_?^6XWI_$JSHG5<@sph{R{yK|YMkb5uC)?U~8g5?^y7FE1b&Q-m zaADh-GvzPZ_UFPJu`K$PB2Asr7c3FL1w1OPkG$%2I6u?Ia{;05OT}RoY^34|DESbI zY|fEL*g*XGLqYEu0oR3aIoZEY`l}nY&KHjAxR`XoL#I-HzE${A7Q0NDmbIMD=V1tx zyLMu!)`Bwp%A#FLnmIJ@t%cX?dP*WhJq|$Gy?gvT{$*jWGJi1r8v*?_h~5pVlbyzo zZ^gitoahSc9t{kYK+`^|Q-u`(a&QU59_urt4fhBwYqp|Ge6lx_VtiyNtG1R154>9I za12tQP9dbtxB6~EppIh(@TJv~Uuf$&^9%&7n&m)cMvo54LDcM+eS4*3NCkG`Ea{Uu zo?Skzis&Ewfs+C-$y%aMN+N4ZLA>TI$Mw+6Cm@T6L>>cBp&7yU3ep8>g}rjM6h&l6 zcQttt5r&{d@`jlT0`#{nox{7|w*DjQe|LhAB~dTQ`ahkZn_aQQciy{Y8Am-2A?Dsh z7Nz%hzf622FhB;!)iN^br5SiuUV-^kqe*v0$?&$bT+d@&TC#VU3MY5^brz{_J?HrG z{?8rZ=wTf{t@sUs!-j!OUbt?0nwiH+q1MsNT*E{y4nIpP=Wwb)$Xa3PdN^#29+J=k zTQyhcw%9ay>K|WuA=4vI=d9?@-@AMFXlO?bXS$WZbgAh~5DhL{Thb<`^9{ zEJgX|wR$qR=0+y{kHDvWA@V3W+M2~EpZ?SJeep*yL>&8!!Il!sgWdGz{FFSHWP<$U zyTF(B;$~+;xVVf}D==!38)EJ2DUo+HNj`M#osS5#Kpl%1`J00{YSWP(w+T=X@@$=^ zzV^5@S#I~q;C7;oO|dugNl;?OZ3f(yu*!|&l*~s}t&xjR#oh^rE+;&(66JXcV44Sk zxndjTbR)d&n=Nle9Y1_%ukFgVVD<&^b|7)rqO9-OX%xzAlBJrC+i zWY@$=E)GJ9fet?6iui-Iiu+Yc5*?)iT$`5I?QT+j*)%HS9EwA~G=;+tCqA#!yVwzn zGM_7h%V!>sts0uxmBX{Fj8FB)zgu}e-4L~~{-KWop|6BbwkK6Z$dglm1cfT%M4b0! z!>30N0}>$puhOpL`19$h%IS{{GU2HN}%v;U-kx)84#)f zdOlH7lsD}iEo{_lmqOq7MyNROoIzf2+hZ@eHI7~;@z>Pt|O@|D2Tg!sVF{~!n%99=^8VfsZ!?9<4Y6|v-#o43DYRjqe*XfR~ z9r@QB&<*xD6)g=7btP>6F^|AI%-aqnb~u`r=35Ol5+=X=o_kyVT~{o1j%p|jgOjCN&rg7F~ zx63JCx9W-O*d&8Ts`PD6$Reb0YQwWRk**eq)e-v7HK~FHK^Q%e`5PzK4Q>Y`M|Y$7 zM0w8jjI%?cBL10(2Lkr>gGjO*ZSq#-iejo!R)VIFsJy!E`8CxDRb@NIs-02<9o}35 zKq+z|x_|X_zrH2wEEx=Zb?d_CeCLzv(n!cSU+A^`k6%$lo9-Ehn7>7-wj2wd?QZeG!{IuSx29?FT%IqQZwuop}<;3qCqI zGwFJ8=E$cBA}us@dpVf=e*AaIiwMf}7u+&NuN?ICNipK(C8~9gu_sBFoGKy?-X~A# z0<4|tUfnd0D}>5ZfC%7|5WrJ-J5|(<^!Wmql0HgC#39Qe6O<8W66DnxIVT+8g$BoO zxXHdnyr>E>4u4&VgowkH@82R`sqhTuFIX4{o7{`!>!IW?uR(I$n5B-O^3$n8(oVTZ zN7Gty!1 z%86R>tZ695N{h0S8SerG*ur2U>#&BVraB>0=$cF~&Z1+extbbOkzI=0zA`$vY{)kvZX}}&O{H_!|*VUR;8i5 zb2!ZobBzhyVW9{VWfGpJsD43xS?1Euigv}2%s5gmC;)ZQCc;a|^liz`nG*n|L>rYV zx6BO9X_q6XCcCW$iPBt05Jy>|z_b%eg^J60+568#v6)1O4Bv2be}!Je;|gFmz-Gsv z+H3Y~Fdjl|oeHU%F+mPJWuU2NwmQ!(h%;D7=c^iV&p1LjD(`Cn@Q%VqD;WhEU8>(P zYzz|CT#+KfGBEB8Zp7)l)5JNE(h3E820s}~)N!sNRKF|%(Mx>GUvCP9m)K=0XjtA3 z@_|G-fy)vsR4Y#S=Em+NKLRm|I@4o!cAR&AfDy=R9cgb6qx$k!{5f|i1DP7CwR2!y zvdVifoD0wpdiD;EuA(VN%F(R7?>VgO#<;pE)}ZK&zvIx=--1ndjz@h6ymm#<{zTa# z4}9^Z7lE*DDgeMONI@s_MB(EQj&M3)-8TQGeqjDd@iE4hC1zEjvn4CELd8K<7Ib*= z*XdENNTdxX|8*w@j*~Y<=!YuPjnp^rHtko^H`HMPS+x=00x5}?E!9^W?^2oM7Qb{T z&zBv09Y;ygSE~6 zifo~SX&Iq3ha3`>he>006D>8?X}UUmo=LbOn2U2UD^?^sp@Z9l&#FC^xS9X;A&`kq zzQFL)_x9bv(?UaA4HIapG%7w+z)eX@H$W?8Ws_n4z8wY-dc_JjrE#Y`wM>N&k|zu? zsY`1*r$s8GQP6tr{vow>4dN4OgVnvOi>fm%(v78DBq7&g z(Oz31cR3t96uNAWvdI zf@mXfz!3=a`5KOwt~}0d(JNtHZ#f7JtT`~x{>&G|?4-{J5g)KJJVM}s1Na972&)n4 zWK_aoSi`S)qE8T`$-MaNtSKUS7$U@AiC>;on=zb=F<+mQJy8zrF$lj$zI13!O^`LWXRRgk{AfiCZ32`1+f0m0A0*KU>k5l-Dbj!X?oHszkxD?nx* zH2u<+bEC^3Onb=f)V-Fcop|p82glyu`q~O!i2v~QSNYjJqur_x4WbSA-dhzBFq!?X z?c$d=Nu_(Pq3I!E?{_^2si)WY2bhA=p`q=S^16crf}E%u@HD7Q{BF`|I-$N@v~qg_4oVw+ZQc%Kaxo4B60hDOFfP=@hk=?rhqLwkzZl4*b792jtpF9-j74p}pyUw4sCm!o* zDlPjwkhje$o#X0$t|UzL&m)$$#V$vl^kjyLefv@dRJo%Kxw1Pio8&S<$Lcujn?|gm#H(HPlfPC|R7lJh>c-Cs7=Gfb48`C1EI%hK_ z|4=tn8R7hBag;6AtNeYm?=un)) zQn=Ttr54y>h~yR$4q#Pf*rP~V8k!pFa!q!yLQ9L{0p@856O>c!x}bXF3M5w|lW(`X znR!)7OY?$O;}tupj0pFn_u7Jl_cGr0|s1gd9cn`b0;MgwC%BZ|ALRzAp1Bub0PGVC z_3zffCvR6>8#}be^KoIv(<9p+Qs{hVR;q+jv7nzD>pCaQh}>&Lst8^8MTG?%+3-=K z#dDw`LG-g4AYjp&a=udFYKiOi!JeL|$t-mF_}s@7|cVXMLdOAQMBkP8NR zKXATP6`QR3LYBw$+G5`wj`5#2A|^R20dw6jywKQ)MnJ_~ zWV06(QTz5EWaEh>5@CBH6D_~A@WLgqxM4yThODAOrQox&bH(zRg~|4if(osbimPVI ziN$!(zUTl8z)@(bsx(Rm6W1xmbT#cJUX!ZqykU2yQx0k@X5p3Z(#ZFj*jh2RfPSHb zjwX$^jWhAR@_f5#JCHyfof!u)F9-&Yc3`@t!f56DdhYjA9j*Q3Js^!EoH zCx|%{3Poiz!Y~?ArdJp}9uPc); zZ?!l3efbZ0p{#hVrO~)@X7I(wUvVSc`0FryRt9$ktfvajl}?d#Rjrp{vb95A