From: Ioakeim Samaras Date: Tue, 23 Jul 2019 15:36:37 +0000 (+0300) Subject: [UI] Support UI partial control X-Git-Tag: 2.0.0~45^2 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=2eba847ebb6acb2686be08eb1cdafc1b12071e7d;p=validation.git [UI] Support UI partial control The UI is capable of retrieving the results from Nexus that every blueprint owner has independently pushed. JIRA: VAL-38 Signed-off-by: Ioakeim Samaras Change-Id: I256641d1faed21025bc688a4a469f7af5f43d45f --- diff --git a/.coafile b/.coafile index 206fc17..ba91275 100644 --- a/.coafile +++ b/.coafile @@ -54,7 +54,11 @@ ignore = ui/target/**, 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/client/jenkins/resources/**.java, - ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/**.java + ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/**.java, + ui/src/main/java/org/akraino/validation/ui/data/SubmissionData.java, + ui/src/main/java/org/akraino/validation/ui/service/DbResultAdapter.java, + ui/src/main/java/org/akraino/validation/ui/client/nexus/NexusExecutorClient.java, + ui/src/main/java/org/akraino/validation/ui/daoimpl/ValidationTestResultDAOImpl.java [all.JS] bears = ESLintBear,JSComplexityBear @@ -66,6 +70,11 @@ ignore = ui/src/main/webapp/app/fusion/**, ui/src/main/webapp/static/**, ui/bin/**, ui/target/**, - ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmission.js, - ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissions.js, - ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionId.js + ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.js, + ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.js, + ui/src/main/webapp/app/BluvalUI/GetBySubmissionId/GetBySubmissionId.js, + ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.js, + ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.js, + ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.js, + ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.js, + ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.js diff --git a/docker/README.rst b/docker/README.rst index 7179bee..581aa37 100644 --- a/docker/README.rst +++ b/docker/README.rst @@ -82,7 +82,7 @@ The mariadb container Building and pushing the container ---------------------------------- -To build just the postgresql container, use the command: +To build just the mariadb container, use the command: .. code-block:: console @@ -100,6 +100,7 @@ In order for the container to be easily created, the deploy.sh script has been d 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 +MARIADB_AKRAINO_PASSWORD, the desired mariadb akraino user password, this variable is required UI_ADMIN_PASSWORD, the desired Blueprint Validation UI password for the admin user, this variable is required UI_AKRAINO_PASSWORD, the desired Blueprint Validation UI password for the akraino user, this variable is required REGISTRY, registry of the mariadb image, default value is akraino @@ -115,14 +116,13 @@ Example (assuming the default variables have been utilized for building the imag .. code-block:: console cd validation/docker/mariadb - ./deploy.sh MARIADB_ROOT_PASSWORD=password UI_ADMIN_PASSWORD=admin UI_AKRAINO_PASSWORD=akraino + ./deploy.sh MARIADB_ROOT_PASSWORD=root_password MARIADB_AKRAINO_PASSWORD=akraino_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 @@ -136,7 +136,7 @@ Example (assuming the default variables have been utilized for building the imag .. code-block:: console cd validation/docker/mariadb - ./deploy_with_existing_persistent_storage.sh MARIADB_ROOT_PASSWORD=password + ./deploy_with_existing_persistent_storage.sh More info can be found at the UI README file. @@ -163,13 +163,13 @@ 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, 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, the mariadb root user password, this variable is required +DB_IP_PORT, the IP and port of the maridb instance, this variable is required +MARIADB_AKRAINO_PASSWORD, the mariadb akraino 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_URL, the URL of the Jenkins instance (http or https must be defined), 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 @@ -191,7 +191,7 @@ Example (assuming the default variables have been utilized for building the imag .. 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 + ./deploy.sh DB_IP_PORT=172.17.0.3:3306 MARIADB_AKRAINO_PASSWORD=akraino_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/deploy.sh b/docker/mariadb/deploy.sh index fec5a2c..df7bcc6 100755 --- a/docker/mariadb/deploy.sh +++ b/docker/mariadb/deploy.sh @@ -16,12 +16,12 @@ # 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" +DOCKER_VOLUME_NAME="akraino-validation-mariadb" # Container name CONTAINER_NAME="akraino-validation-mariadb" # Container input variables MARIADB_ROOT_PASSWORD="" +MARIADB_AKRAINO_PASSWORD="" UI_ADMIN_PASSWORD="" UI_AKRAINO_PASSWORD="" # Image data @@ -41,6 +41,7 @@ do TAG_VER) TAG_VER=${VALUE} ;; TAG_PRE) TAG_PRE=${VALUE} ;; MARIADB_ROOT_PASSWORD) MARIADB_ROOT_PASSWORD=${VALUE} ;; + MARIADB_AKRAINO_PASSWORD) MARIADB_AKRAINO_PASSWORD=${VALUE} ;; CONTAINER_NAME) CONTAINER_NAME=${VALUE} ;; MARIADB_HOST_PORT) MARIADB_HOST_PORT=${VALUE} ;; UI_ADMIN_PASSWORD) UI_ADMIN_PASSWORD=${VALUE} ;; @@ -55,6 +56,12 @@ if [ -z "$MARIADB_ROOT_PASSWORD" ] exit 1 fi +if [ -z "$MARIADB_AKRAINO_PASSWORD" ] + then + echo "ERROR: You must specify the mariadb database akraino user password" + exit 1 +fi + if [ -z "$UI_ADMIN_PASSWORD" ] then echo "ERROR: You must specify the password of the UI admin user" @@ -68,6 +75,7 @@ if [ -z "$UI_AKRAINO_PASSWORD" ] 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 +chmod 0444 "/$(pwd)/mariadb.conf" +docker run --detach --name $CONTAINER_NAME --publish $MARIADB_HOST_PORT:3306 -v $DOCKER_VOLUME_NAME:/var/lib/mysql -v "/$(pwd)/mariadb.conf:/etc/mysql/conf.d/my.cnf" -e MYSQL_ROOT_PASSWORD="$MARIADB_ROOT_PASSWORD" -e MYSQL_DATABASE="akraino" -e MYSQL_USER="akraino" -e MYSQL_PASSWORD="$MARIADB_AKRAINO_PASSWORD" -e UI_ADMIN_PASSWORD="$UI_ADMIN_PASSWORD" -e UI_AKRAINO_PASSWORD="$UI_AKRAINO_PASSWORD" $IMAGE 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 ;' +sleep 10 diff --git a/docker/mariadb/deploy_with_existing_persistent_storage.sh b/docker/mariadb/deploy_with_existing_persistent_storage.sh index a20be5b..b109300 100755 --- a/docker/mariadb/deploy_with_existing_persistent_storage.sh +++ b/docker/mariadb/deploy_with_existing_persistent_storage.sh @@ -16,12 +16,9 @@ # 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" +DOCKER_VOLUME_NAME="akraino-validation-mariadb" # Container name CONTAINER_NAME="akraino-validation-mariadb" -# Container input variables -MARIADB_ROOT_PASSWORD="" # Image data REGISTRY=akraino NAME=validation @@ -40,12 +37,10 @@ do 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 +docker run --detach --name $CONTAINER_NAME --publish $MARIADB_HOST_PORT:3306 -v $DOCKER_VOLUME_NAME:/var/lib/mysql -v "/$(pwd)/mariadb.conf:/etc/mysql/conf.d/my.cnf" $IMAGE sleep 10 -docker exec $CONTAINER_NAME /bin/bash -c 'rm -rf /docker-entrypoint-initdb.d/*.sql' diff --git a/docker/ui/deploy.sh b/docker/ui/deploy.sh index 6b77dd9..c1be674 100755 --- a/docker/ui/deploy.sh +++ b/docker/ui/deploy.sh @@ -22,12 +22,12 @@ NAME=validation TAG_PRE=ui TAG_VER=latest # Container input parameters -MARIADB_ROOT_PASSWORD="" +MARIADB_AKRAINO_PASSWORD="" JENKINS_URL="" JENKINS_USERNAME="" JENKINS_USER_PASSWORD="" JENKINS_JOB_NAME="" -DB_CONNECTION_URL="" +DB_IP_PORT="" NEXUS_PROXY="" JENKINS_PROXY="" @@ -40,12 +40,12 @@ do NAME) NAME=${VALUE} ;; TAG_PRE) TAG_PRE=${VALUE} ;; TAG_VER) TAG_VER=${VALUE} ;; - MARIADB_ROOT_PASSWORD) MARIADB_ROOT_PASSWORD=${VALUE} ;; + MARIADB_AKRAINO_PASSWORD) MARIADB_AKRAINO_PASSWORD=${VALUE} ;; JENKINS_URL) JENKINS_URL=${VALUE} ;; JENKINS_USERNAME) JENKINS_USERNAME=${VALUE} ;; JENKINS_USER_PASSWORD) JENKINS_USER_PASSWORD=${VALUE} ;; JENKINS_JOB_NAME) JENKINS_JOB_NAME=${VALUE} ;; - DB_CONNECTION_URL) DB_CONNECTION_URL=${VALUE} ;; + DB_IP_PORT) DB_IP_PORT=${VALUE} ;; CONTAINER_NAME) CONTAINER_NAME=${VALUE} ;; NEXUS_PROXY) NEXUS_PROXY=${VALUE} ;; JENKINS_PROXY) JENKINS_PROXY=${VALUE} ;; @@ -53,15 +53,15 @@ do esac done -if [ -z "$DB_CONNECTION_URL" ] +if [ -z "$DB_IP_PORT" ] then - echo "ERROR: You must specify the database connection url" + echo "ERROR: You must specify the database IP and port" exit 1 fi -if [ -z "$MARIADB_ROOT_PASSWORD" ] +if [ -z "$MARIADB_AKRAINO_PASSWORD" ] then - echo "ERROR: You must specify the mariadb root user password" + echo "ERROR: You must specify the mariadb akraino user password" exit 1 fi @@ -90,5 +90,5 @@ if [ -z "$JENKINS_JOB_NAME" ] fi IMAGE="$REGISTRY"/"$NAME":"$TAG_PRE"-"$TAG_VER" -docker run --name $CONTAINER_NAME --network="host" -it --rm -e DB_CONNECTION_URL="$DB_CONNECTION_URL" -e MARIADB_ROOT_PASSWORD="$MARIADB_ROOT_PASSWORD" -e JENKINS_URL="$JENKINS_URL" -e JENKINS_USERNAME="$JENKINS_USERNAME" -e JENKINS_USER_PASSWORD="$JENKINS_USER_PASSWORD" -e JENKINS_JOB_NAME="$JENKINS_JOB_NAME" -e NEXUS_PROXY="$NEXUS_PROXY" -e JENKINS_PROXY="$JENKINS_PROXY" $IMAGE +docker run --detach --name $CONTAINER_NAME --network="host" -e DB_IP_PORT="$DB_IP_PORT" -e MARIADB_AKRAINO_PASSWORD="$MARIADB_AKRAINO_PASSWORD" -e JENKINS_URL="$JENKINS_URL" -e JENKINS_USERNAME="$JENKINS_USERNAME" -e JENKINS_USER_PASSWORD="$JENKINS_USER_PASSWORD" -e JENKINS_JOB_NAME="$JENKINS_JOB_NAME" -e NEXUS_PROXY="$NEXUS_PROXY" -e JENKINS_PROXY="$JENKINS_PROXY" $IMAGE sleep 10 diff --git a/ui/CHANGELOG.md b/ui/CHANGELOG.md index 6f41f59..0e636d2 100644 --- a/ui/CHANGELOG.md +++ b/ui/CHANGELOG.md @@ -124,3 +124,33 @@ All notable changes to this project will be documented in this file. ### Removed - Unused credentials in music.properties file + +## [0.2.0-SNAPSHOT] - 30 August 2019 +### Added +- Partial loop is supported +- LAB parameter is now being sent towards Jenkins +- Logout process is supported +- Results are retrieved by timestamp, last run and based on date +- For DB results, a common thread-safe adapter is used + +### Changed +- The common Nexus URL is now also used for full control loop mode. +- Only the IP and port are needed to be defined regarding DB identification process +- 'v1' has been added in REST API URLs +- Small letters are used for all the view names +- Bug with infinite nested ng-repeat loops fixed +- The name of war file has been changed from 'AECBlueprintValidationUI' to 'bluvalui'. +- Bug fixed regarding the display of the overall result. +- Host verifiers and trust certificates have been moved from clients to 'UiInitializer' spring component. +- UI docker container is detached when it is deployed +- README file has been updated to include instructions regarding installation of needed tools for the development mode +- 200 most recent results are retrieved on each nexus scan loop +- A common diplay test suite view is used now +- DB results have been divided in order to support layer as a key +- DB akraino user is used instead of DB root user +- test.info.yaml parsing is supported +- Selection of optional test cases is supported +- Pagination table is supported for committed submissions + +### Removed + diff --git a/ui/README.rst b/ui/README.rst index eae8f30..8006953 100644 --- a/ui/README.rst +++ b/ui/README.rst @@ -31,8 +31,6 @@ In specific, the purpose of the UI is twofold: 2) Partial control of producing results. In this mode, the UI must be connected with a mariadb instance and the Nexus server where the results are stored. Every blueprint owner is responsible of executing tests and storing results in Nexus using his/her own Jenkins instance. The UI only retrieves results from Nexus and displays them. -Currently, the partial control loop is not supported. - In both modes, user authentication, authorization and accounting (AAA) will be supported in order to control access to resources, enforce policies on these resources and audit their usage. Prerequisites: @@ -81,6 +79,89 @@ Download the project Prerequisites ~~~~~~~~~~~~~ +- Tools + +In order to setup the development environment, the following tools are needed: +- JDK 1.8 +- Maven +- docker +- MySQL client + +Execute the commands below in order to install these tools (note that the PROXY_IP and PROXY_PORT variables must be substituted with the ones that are used by the hosting operating system) + +If the host is behind a proxy, define this proxy using the following commands: + +.. code-block:: console + sudo touch /etc/apt/apt.conf.d/proxy.conf + sudo sh -c 'echo "Acquire::http::proxy \"http://:/\";" >> /etc/apt/apt.conf.d/proxy.conf' + sudo sh -c 'echo "Acquire::https::proxy \"https://:/\";" >> /etc/apt/apt.conf.d/proxy.conf' + sudo sh -c 'echo "Acquire::ftp::proxy \"ftp://:/\";" >> /etc/apt/apt.conf.d/proxy.conf' + sudo apt-get update + export http_proxy=http://: + export https_proxy=http://: + +Install jdk and maven using the following commands: + +.. code-block:: console + sudo apt install default-jdk + sudo apt install maven + +If the host is behind a proxy, configure this proxy for maven: + +.. code-block:: console + nano ~/.m2/settings.xml + + + + + + true + http + + + 127.0.0.1|localhost + + + https + true + https + + + 127.0.0.1|localhost + + + + + + +Install docker using the following commands: + +.. code-block:: console + sudo apt install docker.io + sudo groupadd docker + sudo gpasswd -a $USER docker + newgrp docker + +If the host is behind a proxy, configure docker to use this proxy: + +.. code-block:: console + mkdir /etc/systemd/system/docker.service.d + sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf + + + [Service] + Environment="HTTP_PROXY=http://:/" + + + + sudo systemctl daemon-reload + sudo systemctl restart docker + +Install mySQL client: + +.. code-block:: console + sudo apt install mysql-client + - Database A mariadb database instance is needed for both modes of the UI with the appropriate databases and tables in order for the back-end system to store and retrieve data. @@ -91,6 +172,7 @@ Also, a script has been developed, namely validation/docker/mariadb/deploy.sh wh 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 +MARIADB_AKRAINO_PASSWORD, the desired mariadb akraino user password, this variable is required UI_ADMIN_PASSWORD, the desired Blueprint Validation UI password for the admin user, this variable is required UI_AKRAINO_PASSWORD, the desired Blueprint Validation UI password for the akraino user, this variable is required REGISTRY, registry of the mariadb image, default value is akraino @@ -99,19 +181,19 @@ 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 -Currently, two users are supported for the UI, namely admin (full privileges) and akraino (limited privileges). Their passwords must be defined in the database. +Currently, two users are supported by the UI, namely admin (full privileges) and akraino (limited privileges). Their passwords must be defined in the database. In order to build and deploy the image using only the required parameters, the below instructions should be followed: -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: +The mariadb root password, mariadb akraino user password (currently the UI connects to the database using the akraino user), 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 -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 + ./deploy.sh TAG_PRE=dev-mariadb MARIADB_ROOT_PASSWORD= MARIADB_AKRAINO_PASSWORD= UI_ADMIN_PASSWORD= UI_AKRAINO_PASSWORD= + mysql -p -uakraino -h < ../../ui/db-scripts/examples/initialize_db_example.sql In order to retrieve the IP of the mariadb container, the following command should be executed: @@ -121,12 +203,11 @@ In order to retrieve the IP of the mariadb container, the following command shou 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). -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 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 'akraino-validation-mariadb' docker volume is used), a different approach should be used after the image building process. 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 @@ -135,23 +216,23 @@ MARIADB_HOST_PORT, the port on which mariadb is exposed on host, default value i 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: +The mariadb root user password 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= + ./deploy_with_existing_persistent_storage.sh TAG_PRE=dev-mariadb -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). +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 used docker volume 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 - sudo rm -rf /var/lib/mariadb + docker volume rm akraino-validation-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 + ./deploy.sh TAG_PRE=dev-mariadb MARIADB_ROOT_PASSWORD= MARIADB_AKRAINO_PASSWORD= UI_ADMIN_PASSWORD= UI_AKRAINO_PASSWORD= + mysql -p -uakraino -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: @@ -161,7 +242,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 it was performed 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 -uakraino -h < ../../ui/db-scripts/examples/initialize_db_example.sql' command): db-scripts/examples/initialize_db_example.sql @@ -208,7 +289,7 @@ Then, the following command should be executed: .. code-block:: console - mysql -p -uroot -h < ./dbscript.sql + mysql -p -uakraino -h < ./dbscript.sql For example, if a user wants to define a new timeslot with the following data: @@ -228,7 +309,7 @@ Then, the following command should be executed: .. code-block:: console - mysql -p -uroot -h < ./dbscript.sql + mysql -p -uakraino -h < ./dbscript.sql For example, if a user wants to define a new silo with the following data: @@ -248,7 +329,7 @@ Then, the following command should be executed: .. code-block:: console - mysql -p -uroot -h < ./dbscript.sql + mysql -p -uakraino -h < ./dbscript.sql Furthermore, if a user wants to define a new blueprint, namely "newBlueprint" and a new instance of this blueprint with the following data: @@ -267,7 +348,7 @@ Then, the following command should be executed: .. code-block:: console - mysql -p -uroot -h < ./dbscript.sql + mysql -p -uakraino -h < ./dbscript.sql The UI will automatically retrieve this new data and display it to the user. @@ -279,18 +360,13 @@ It should be noted that it is not the UI responsibility to deploy a Jenkins inst Furthermore, this instance must have the following option enabled: "Manage Jenkins -> Configure Global Security -> Prevent Cross Site Request Forgery exploits". -Also, currently, the corresponding Jenkins job should accept the following as input parameters: "SUBMISSION_ID", "BLUEPRINT", "VERSION", "LAYER" and "UI_IP". +Also, currently, the corresponding Jenkins job should accept the following as input parameters: "SUBMISSION_ID", "BLUEPRINT", "VERSION", "LAYER", "LAB" and "UI_IP". The "SUBMISSION_ID" and "UI_IP" parameters (i.e. IP address of the UI host machine-this is needed by the Jenkins instance in order to send back Job completion notification) are created and provided by the back-end part of the UI. -The "BLUEPRINT", "VERSION" and "LAYER" parameters are configured by the UI user. +The "BLUEPRINT", "VERSION", "LAYER" and "LAB" parameters are configured by the UI user. Moreover, as the Jenkins notification plugin (https://wiki.jenkins.io/display/JENKINS/Notification+Plugin) seems to ignore proxy settings, the corresponding Jenkins job must be configured to execute the following commands at the end (Post-build Actions) -.. code-block:: console - - cookie=`curl -v -H "Content-Type: application/x-www-form-urlencoded" -X POST --insecure --silent http://$UI_IP:8080/AECBlueprintValidationUI/login_external -d "loginId=akraino&password=akraino" 2>&1 | grep "Set-Cookie: " | awk -F ':' '{print $2}'` - curl -v --cookie $cookie -H "Content-Type: application/json" -X POST --insecure --silent http://$UI_IP:8080/AECBlueprintValidationUI/api/jenkinsJobNotification/ --data '{"submissionId": "'"$SUBMISSION_ID"'" , "name":"'"$JOB_NAME"'", "buildNumber":"'"$BUILD_NUMBER"'"}' - -It should be noted that the credentials user=akraino and password=akraino defined in the above commands should be replaced with the credentials of a real UI user. Recall that these credentials are defined in the database. +TBD - Nexus server @@ -298,19 +374,17 @@ All the blueprint validation results are stored in Nexus server for both modes o It should be noted that it is not the UI responsibility to deploy a Nexus server. -In the context of the full control loop, these results must be available in the following url: +These results must be available in the following url: - https://nexus.akraino.org/content/sites/logs//job///results//. + https://nexus.akraino.org/content/sites/logs/////results// -where is the silo used by a lab for storing results in Nexus (for example 'att-blu-val'), is the Jenkins job name that is triggered by the UI, is the number of the Jenkins job that produced this result, is the blueprint layer and is the name of the corresponding test suite. +where is the silo used by a lab for storing results in Nexus (for example 'att-blu-val'), is the name of the blueprint, the the blueprint version, is the timestamp used for producinf the results, is the blueprint layer and is the name of the corresponding test suite. -If multiple test suites are available, multiple test suite names should be created. +Below, an example URL is illustrated -Moreover, the results should be stored in the 'output.xml' file and placed in the aforementioned URL using the following format: - -TBD + https://nexus.akraino.org/content/sites/logs/att-blu-val/rec/master/20190611-132818/results/hardware/bios_version/ -In the context of partial control, the results must be available in the following url: +Moreover, the results should be stored in the 'output.xml' file and placed in the aforementioned URL using the following format: TBD @@ -330,13 +404,13 @@ The pom.xml file supports the building of an appropriate container image using t This script accepts the following as input parameters: 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, the mariadb root user password, this variable is required +DB_IP_PORT, the IP and port of the maridb instance, this variable is required +MARIADB_AKRAINO_PASSWORD, the mariadb akraino 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_URL, the URL of the Jenkins instance (http or https must be defined), 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 @@ -345,8 +419,8 @@ JENKINS_PROXY, the needed proxy in order for the Jenkins server to be reachable, 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 +- The mariadb akraino user password (look at the Database subsection) +- The IP and port of the mariadb - The Jenkins url - The Jenkins username and password - The name of Jenkins Job @@ -358,9 +432,9 @@ Then, the following commands can be executed in order to build and deploy the UI cd validation/ui 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= + ./deploy.sh TAG_PRE=dev-ui DB_IP_PORT= MARIADB_AKRAINO_PASSWORD= JENKINS_URL= JENKINS_USERNAME= JENKINS_USER_PASSWORD= JENKINS_JOB_NAME= -The content of the DB_CONNECTION_URL can be for example 172.17.0.3:3306/akraino (i.e. IP and port of the database container plus '/akraino'). +The content of the DB_IP_PORT can be for example '172.17.0.3:3306'. 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). @@ -368,7 +442,7 @@ If no proxy exists, the proxy ip and port variables should not be defined. The UI should be available in the following url: - http://localhost:8080/AECBlueprintValidationUI + http://localhost:8080/bluvalui/ Note that the deployment uses the network host mode, so the 8080 must be available on the host. @@ -378,12 +452,7 @@ TBD Limitations ----------- -- The partial loop mode is not currently supported. - The UI has been tested using Chrome and Firefox browsers. - The back-end part of the UI does not take into account the start date and time and duration of the configured timeslot. It immediately triggers the corresponding Jenkins Job. - Results data manipulation (filtering, graphical representation, indexing in time order, etc) is not supported. -- Only the following labs are supported: AT&T, Ericsson, Community and Arm. -- Only the following tabs are functional: 'Committed Submissions', 'Blueprint Validation Results -> Get by submission id'. -- The UI configures only the "BLUEPRINT", "VERSION", "LAYER", "SUBMISSION_ID" and "UI_IP" input parameters of the Jenkins job. -- The silos, labs, and the available blueprints and timeslots must be manually configured in the mariadb database. -- Logout action is not currently supported. \ No newline at end of file +- The silos, labs, and the available blueprints and timeslots must be manually configured in the mariadb database. \ No newline at end of file diff --git a/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql b/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql index c248b5b..1dc1742 100644 --- a/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql +++ b/ui/db-scripts/EcompSdkDMLMySql_2_4_OS.sql @@ -26,18 +26,13 @@ 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 (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'); - +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 most recent', 23, 10, 'getmostrecent', '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 timestamp', 23, 10, 'getbytimestamp', '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 last run', 23, 10, 'getlastrun', '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 based on dates', 23, 10, 'getbasedondate', '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); diff --git a/ui/db-scripts/akraino_blueprint_validation_db.sql b/ui/db-scripts/akraino_blueprint_validation_db.sql index 06aa4a8..6b94c2c 100644 --- a/ui/db-scripts/akraino_blueprint_validation_db.sql +++ b/ui/db-scripts/akraino_blueprint_validation_db.sql @@ -18,16 +18,18 @@ 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; +DROP TABLE IF EXISTS w_robot_test_result; +DROP TABLE IF EXISTS validation_test_result; +DROP TABLE IF EXISTS submission; create table lab ( id bigint not NULL AUTO_INCREMENT, - lab text not NULL, + lab text not NULL unique, CONSTRAINT id_pk PRIMARY KEY (id) ); @@ -45,7 +47,7 @@ create table timeslot ( create table silo ( id bigint not NULL AUTO_INCREMENT, silo text not NULL, - lab_id bigint not NULL, + lab_id bigint not NULL unique, CONSTRAINT id_pk PRIMARY KEY (id), CONSTRAINT lab_id_fk2 FOREIGN KEY (lab_id) REFERENCES lab (id) MATCH SIMPLE @@ -69,24 +71,54 @@ CREATE TABLE blueprint_instance_for_validation 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 + ON UPDATE NO ACTION ON DELETE NO ACTION, + unique (version, layer, blueprint_id) ); 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 ); +CREATE TABLE validation_test_result +( + id bigint not NULL AUTO_INCREMENT, + blueprint_name varchar(20) not NULL, + version text not NULL, + lab_id bigint not NULL, + timestamp text, + all_layers boolean, + optional boolean, + result boolean, + submission_id bigint, + date_of_storage text, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT lab_id_fk3 FOREIGN KEY (lab_id) + REFERENCES lab (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT submission_id_fk FOREIGN KEY (submission_id) + REFERENCES submission (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + unique (timestamp, lab_id) +); + +CREATE TABLE w_robot_test_result +( + id bigint not NULL AUTO_INCREMENT, + layer text not NULL, + validation_test_result_id bigint not NULL, + robot_test_results LONGTEXT, + CONSTRAINT id_pk PRIMARY KEY (id), + CONSTRAINT validation_test_result_id_fk FOREIGN KEY (validation_test_result_id) + REFERENCES validation_test_result (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + unique (layer, validation_test_result_id) +); + commit; diff --git a/ui/db-scripts/examples/initialize_db_example.sql b/ui/db-scripts/examples/initialize_db_example.sql index 7902b94..1273ae6 100644 --- a/ui/db-scripts/examples/initialize_db_example.sql +++ b/ui/db-scripts/examples/initialize_db_example.sql @@ -25,14 +25,13 @@ insert into timeslot values(1, 'now', null, 1); insert into silo values(1, 'att-blu-val', 1); insert into blueprint (id, blueprint_name) values(1, 'dummy'); -insert into blueprint (id, blueprint_name) values(2, 'Unicycle'); -insert into blueprint (id, blueprint_name) values(3, 'REC'); - -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(1, 1, 'latest', 0, 'Dummy Hardware'); /* 0 Stands for hardware layer */ -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(2, 3, 'latest', 0, 'AT&T Hardware'); /* 0 Stands for hardware layer */ -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(3, 3, 'latest', 1, 'OS of the AT&T platform'); /* 1 Stands for OS layer */ -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(4, 3, 'latest', 2, 'K8s of the AT&T platform'); /* 2 Stands for K8s layer */ -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(5, 3, 'latest', 7, 'All layers'); /* 7 Stands for all layers */ -insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(6, 2, 'latest', 0, 'Unicycle Hardware'); /* 0 Stands for hardware layer */ +insert into blueprint (id, blueprint_name) values(2, 'unicycle'); +insert into blueprint (id, blueprint_name) values(3, 'rec'); + +insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(1, 1, 'master', 0, 'Dummy Hardware'); /* 0 Stands for hardware layer */ +insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(2, 3, 'master', 0, 'AT&T Hardware'); /* 0 Stands for hardware layer */ +insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(3, 3, 'master', 1, 'OS of the AT&T platform'); /* 1 Stands for OS layer */ +insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(4, 3, 'master', 2, 'K8s of the AT&T platform'); /* 2 Stands for K8s layer */ +insert into blueprint_instance_for_validation (id, blueprint_id, version, layer, layer_description) values(6, 2, 'master', 0, 'Unicycle Hardware'); /* 0 Stands for hardware layer */ commit; diff --git a/ui/pom.xml b/ui/pom.xml index e4736ef..f3f0c97 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -14,8 +14,8 @@ org.akraino.validation ui - 0.1.0-SNAPSHOT - AECBlueprintValidationUI Maven Webapp + 0.2.0-SNAPSHOT + Bluval UI Maven Webapp war @@ -64,7 +64,7 @@ - AECBlueprintValidationUI + bluvalui @@ -144,7 +144,8 @@ - + io.fabric8 docker-maven-plugin @@ -372,6 +373,5 @@ commons-httpclient ${commons-httpclient.version} - diff --git a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/JenkinsExecutorClient.java b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/JenkinsExecutorClient.java index 6c80c24..f4b97a6 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/jenkins/JenkinsExecutorClient.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/jenkins/JenkinsExecutorClient.java @@ -23,19 +23,9 @@ import java.net.Proxy; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; -import java.util.Map; import javax.annotation.Nonnull; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; import javax.ws.rs.core.MultivaluedMap; import org.akraino.validation.ui.client.jenkins.resources.CrumbResponse; @@ -44,6 +34,7 @@ import org.akraino.validation.ui.client.jenkins.resources.Parameters; import org.akraino.validation.ui.client.jenkins.resources.QueueJobItem; import org.apache.commons.httpclient.HttpException; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.stereotype.Service; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientHandlerException; @@ -54,15 +45,14 @@ import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.client.urlconnection.HTTPSProperties; import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; +@Service public final class JenkinsExecutorClient { private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(JenkinsExecutorClient.class); - private static final List JENKINS_CLIENTS = new ArrayList<>(); private static final Object LOCK = new Object(); private final Client client; @@ -70,13 +60,10 @@ public final class JenkinsExecutorClient { private final String password; private final String baseurl; - private final HostnameVerifier hostnameVerifier; - private final TrustManager[] trustAll; - - private JenkinsExecutorClient(String newUser, String newPassword, String newBaseurl) { - this.user = newUser; - this.password = newPassword; - this.baseurl = newBaseurl; + public JenkinsExecutorClient() { + this.baseurl = System.getenv("JENKINS_URL"); + this.user = System.getenv("JENKINS_USERNAME"); + this.password = System.getenv("JENKINS_USER_PASSWORD"); ClientConfig clientConfig = new DefaultClientConfig(); clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); this.client = new Client(new URLConnectionClientHandler(new HttpURLConnectionFactory() { @@ -97,44 +84,6 @@ public final class JenkinsExecutorClient { } }), clientConfig); this.client.addFilter(new HTTPBasicAuthFilter(user, password)); - // Create all-trusting host name verifier - hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - // Create a trust manager that does not validate certificate chains - trustAll = new TrustManager[] {new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; // Not relevant. - } - - @Override - public void checkClientTrusted(X509Certificate[] certs, String authType) { - // Do nothing. Just allow them all. - } - - @Override - public void checkServerTrusted(X509Certificate[] certs, String authType) { - // Do nothing. Just allow them all. - } - }}; - } - - public static synchronized JenkinsExecutorClient getInstance(@Nonnull String newUser, @Nonnull String newPassword, - @Nonnull String newBaseurl) throws MalformedURLException { - new URL(newBaseurl); - for (JenkinsExecutorClient client : JENKINS_CLIENTS) { - if (client.getBaseUrl().equals(newBaseurl) && client.getUser().equals(newUser) - && client.getPassword().equals(newPassword)) { - return client; - } - } - JenkinsExecutorClient client = new JenkinsExecutorClient(newUser, newPassword, newBaseurl); - JENKINS_CLIENTS.add(client); - return client; } public String getUser() { @@ -150,7 +99,7 @@ public final class JenkinsExecutorClient { } public QueueJobItem getQueueJobItem(URL queueJobItemUrl) throws HttpException, ClientHandlerException, - UniformInterfaceException, KeyManagementException, NoSuchAlgorithmException { + UniformInterfaceException, KeyManagementException, NoSuchAlgorithmException { synchronized (LOCK) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get a Jenkins resource"); String crumb = this.getCrumb(); @@ -159,29 +108,17 @@ public final class JenkinsExecutorClient { LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); WebResource.Builder builder = webResource.getRequestBuilder(); builder.header("Jenkins-Crumb", crumb); - ClientResponse response = - builder.accept("application/json").type("application/json").get(ClientResponse.class); + ClientResponse response = builder.accept("application/json").type("application/json") + .get(ClientResponse.class); if (response.getStatus() != 200) { throw new HttpException("Get on Jenkins failed. HTTP error code : " + response.getStatus() - + " and message: " + response.getEntity(String.class)); + + " and message: " + response.getEntity(String.class)); } LOGGER.info(EELFLoggerDelegate.applicationLogger, "Get of Jenkins resource succeeded"); return response.getEntity(QueueJobItem.class); } } - /** - * - * @param jobName - * @param parameters - * @return The URL of the corresponding Jenkins queue job item - * @throws UniformInterfaceException - * @throws ClientHandlerException - * @throws HttpException - * @throws MalformedURLException - * @throws NoSuchAlgorithmException - * @throws KeyManagementException - */ public URL postJobWithQueryParams(@Nonnull String jobName, @Nonnull Parameters parameters) throws HttpException, ClientHandlerException, UniformInterfaceException, MalformedURLException, KeyManagementException, NoSuchAlgorithmException { @@ -194,15 +131,15 @@ public final class JenkinsExecutorClient { queryParams = queryParams + parameter.getName() + "=" + parameter.getValue() + "&"; } queryParams = queryParams.substring(0, queryParams.length() - 1); - WebResource webResource = - this.client.resource(this.getBaseUrl() + "/job/" + jobName + "/buildWithParameters" + queryParams); + WebResource webResource = this.client + .resource(this.getBaseUrl() + "/job/" + jobName + "/buildWithParameters" + queryParams); LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of post: " + webResource.getURI().toString()); WebResource.Builder builder = webResource.getRequestBuilder(); builder.header("Jenkins-Crumb", crumb); ClientResponse response = builder.type("application/json").post(ClientResponse.class, String.class); if (response.getStatus() != 200 && response.getStatus() != 201) { throw new HttpException("Post of Jenkins job failed. HTTP error code : " + response.getStatus() - + " and message: " + response.getEntity(String.class)); + + " and message: " + response.getEntity(String.class)); } LOGGER.info(EELFLoggerDelegate.applicationLogger, "Jenkins job has been successfully triggered"); URL buildQueueUrl = null; @@ -219,32 +156,19 @@ public final class JenkinsExecutorClient { } private String getCrumb() throws HttpException, ClientHandlerException, UniformInterfaceException, - KeyManagementException, NoSuchAlgorithmException { + KeyManagementException, NoSuchAlgorithmException { LOGGER.info(EELFLoggerDelegate.applicationLogger, "Attempting to get the crumb"); - setProperties(); String crumbUri = baseurl + "/crumbIssuer/api/json"; WebResource webResource = this.client.resource(crumbUri); - ClientResponse response = - webResource.accept("application/json").type("application/json").get(ClientResponse.class); + ClientResponse response = webResource.accept("application/json").type("application/json") + .get(ClientResponse.class); if (response.getStatus() == 201 || response.getStatus() == 200) { CrumbResponse crumbResponse = response.getEntity(CrumbResponse.class); LOGGER.info(EELFLoggerDelegate.applicationLogger, "Successful crumb retrieval"); return crumbResponse.getCrumb(); } throw new HttpException("Get crumb attempt towards Jenkins failed. HTTP error code: " + response.getStatus() - + " and message: " + response.getEntity(String.class)); - } - - private void setProperties() throws NoSuchAlgorithmException, KeyManagementException { - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, this.trustAll, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); - // Install the all-trusting host verifier - HttpsURLConnection.setDefaultHostnameVerifier(this.hostnameVerifier); - DefaultClientConfig config = new DefaultClientConfig(); - Map properties = config.getProperties(); - HTTPSProperties httpsProperties = new HTTPSProperties((str, sslSession) -> true, sslContext); - properties.put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, httpsProperties); + + " and message: " + response.getEntity(String.class)); } } 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 7ee7239..30206bf 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 @@ -22,20 +22,24 @@ import java.net.Proxy; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; import java.util.List; -import java.util.Map; +import java.util.Locale; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; +import javax.annotation.Nonnull; import org.akraino.validation.ui.client.nexus.resources.RobotTestResult; -import org.akraino.validation.ui.client.nexus.resources.WrapperRobotTestResult; +import org.akraino.validation.ui.client.nexus.resources.Status; +import org.akraino.validation.ui.client.nexus.resources.TestInfoYaml; +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.client.nexus.resources.WRobotNexusTestResult; import org.akraino.validation.ui.data.BlueprintLayer; import org.apache.commons.httpclient.HttpException; import org.json.JSONObject; @@ -44,12 +48,16 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.stereotype.Service; 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; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientResponse; @@ -58,21 +66,19 @@ import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.client.urlconnection.HTTPSProperties; import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; +@Service public final class NexusExecutorClient { private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(NexusExecutorClient.class); private final Client client; private final String baseurl; - private final HostnameVerifier hostnameVerifier; - private final TrustManager[] trustAll; - public NexusExecutorClient(String newBaseurl) { - this.baseurl = newBaseurl; + public NexusExecutorClient() { + this.baseurl = PortalApiProperties.getProperty("nexus_url"); ClientConfig clientConfig = new DefaultClientConfig(); clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); this.client = new Client(new URLConnectionClientHandler(new HttpURLConnectionFactory() { @@ -81,10 +87,10 @@ public final class NexusExecutorClient { @Override public HttpURLConnection getHttpURLConnection(URL url) throws IOException { try { - String proxyIp = - System.getenv("NEXUS_PROXY").substring(0, System.getenv("NEXUS_PROXY").lastIndexOf(":")); - String proxyPort = - System.getenv("NEXUS_PROXY").substring(System.getenv("NEXUS_PROXY").lastIndexOf(":") + 1); + String proxyIp = System.getenv("NEXUS_PROXY").substring(0, + System.getenv("NEXUS_PROXY").lastIndexOf(":")); + String proxyPort = System.getenv("NEXUS_PROXY") + .substring(System.getenv("NEXUS_PROXY").lastIndexOf(":") + 1); proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.parseInt(proxyPort))); return (HttpURLConnection) url.openConnection(proxy); } catch (Exception ex) { @@ -92,42 +98,289 @@ public final class NexusExecutorClient { } } }), clientConfig); - // Create all-trusting host name verifier - hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; + } + + public String getBaseUrl() { + return this.baseurl; + } + + public List getResource(String endpoint) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException { + List resources = new ArrayList(); + String nexusUrl = this.baseurl; + if (endpoint != null) { + nexusUrl = this.baseurl + "/" + endpoint; + } + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get nexus resource: " + nexusUrl); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve nexus resource " + nexusUrl + ". HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + for (int i = 2; i < elements.size(); i++) { + String resource = elements.get(i).getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + resource = resource.substring(0, resource.length() - 1); + resources.add(resource); + } + return resources; + } + + public List getResource(@Nonnull String endpoint1, @Nonnull String endpoint2) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException { + String endpoint = endpoint1 + "/" + endpoint2; + return this.getResource(endpoint); + } + + public List getResource(@Nonnull String endpoint1, @Nonnull String endpoint2, @Nonnull String endpoint3) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException { + String endpoint = endpoint1 + "/" + endpoint2 + "/" + endpoint3; + return this.getResource(endpoint); + } + + public ValidationNexusTestResult getResult(@Nonnull String name, @Nonnull String version, @Nonnull String siloText, + @Nonnull String timestamp) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException, NullPointerException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version; + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get validation nexus test result"); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve validation nexus test result. HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + Element element = findElementByTimestamp(elements.subList(2, elements.size()), timestamp); + if (element == null) { + return null; + } + ValidationNexusTestResult vNexusResult = new ValidationNexusTestResult(); + vNexusResult.setBlueprintName(name); + vNexusResult.setSilo(siloText); + vNexusResult.setVersion(version); + vNexusResult.setTimestamp(timestamp); + String lastModified = element.getElementsByTag("td").get(1).text(); + vNexusResult.setDateOfStorage(lastModified); + TestInfoYaml testInfo = getTestInfo(webResource.getURI().toString() + timestamp); + if (testInfo != null) { + if (testInfo.gettest_info().getLayer().equals("all")) { + vNexusResult.setAllLayers(true); + } else { + vNexusResult.setAllLayers(false); } - }; - // Create a trust manager that does not validate certificate chains - trustAll = new TrustManager[] {new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; // Not relevant. + vNexusResult.setOptional(testInfo.gettest_info().getOptional()); + } + List wTestResults = getWRobotTestResults(name, version, siloText, timestamp); + vNexusResult.setwRobotNexusTestResults(wTestResults); + vNexusResult.setResult(determineResult(wTestResults)); + return vNexusResult; + } + + public List getResults(@Nonnull String name, @Nonnull String version, + @Nonnull String siloText, int noOfLastElements) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version; + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get validation Nexus test results"); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve validation Nexus test results. HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + List vNexusResults = new ArrayList(); + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + elements = findLastElementsByDate(elements.subList(2, elements.size()), noOfLastElements); + for (int i = 0; i < elements.size(); i++) { + try { + String timestamp = elements.get(i).getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + timestamp = timestamp.substring(0, timestamp.length() - 1); + ValidationNexusTestResult vNexusResult = this.getResult(name, version, siloText, timestamp); + vNexusResults.add(vNexusResult); + } catch (HttpException ex) { + LOGGER.warn(EELFLoggerDelegate.auditLogger, "Exception occured while retrieving timestamp results"); + continue; } + } + return vNexusResults; + } - @Override - public void checkClientTrusted(X509Certificate[] certs, String authType) { - // Do nothing. Just allow them all. + public List getResults(@Nonnull String name, @Nonnull String version, + @Nonnull String siloText, @Nonnull Date date) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException, NullPointerException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version; + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get validation Nexus results based on date"); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve validation Nexus results based on date. HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + List vNexusResults = new ArrayList(); + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + elements = findElementsBasedOnDate(elements.subList(2, elements.size()), date); + for (int i = 0; i < elements.size(); i++) { + try { + String timestamp = elements.get(i).getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + timestamp = timestamp.substring(0, timestamp.length() - 1); + ValidationNexusTestResult vNexusResult = this.getResult(name, version, siloText, timestamp); + vNexusResults.add(vNexusResult); + } catch (HttpException ex) { + LOGGER.warn(EELFLoggerDelegate.auditLogger, "Exception occured while retrieving timestamp results"); + continue; } + } + return vNexusResults; + } + public ValidationNexusTestResult getLastResultBasedOnOutcome(@Nonnull String name, @Nonnull String version, + @Nonnull String siloText, List layers, Boolean optional, boolean outcome) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException, NullPointerException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version; + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get last result based on outcome"); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve last result based on outcome from Nexus. HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + elements = elements.subList(2, elements.size()); + if (elements.size() < 1) { + return null; + } + DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + Collections.sort(elements, new Comparator() { @Override - public void checkServerTrusted(X509Certificate[] certs, String authType) { - // Do nothing. Just allow them all. + public int compare(Element element1, Element element2) { + try { + return dateFormat.parse(element2.getElementsByTag("td").get(1).text()) + .compareTo(dateFormat.parse(element1.getElementsByTag("td").get(1).text())); + } catch (ParseException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when parsing date. " + UserUtils.getStackTrace(e)); + return 0; + } + } + }); + for (Element element : elements) { + try { + String elementTimestamp = element.getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + elementTimestamp = elementTimestamp.substring(0, elementTimestamp.length() - 1); + ValidationNexusTestResult vNexusResult = this.getResult(name, version, siloText, elementTimestamp); + if (vNexusResult.getResult() != outcome) { + continue; + } + if (optional != null && vNexusResult.getOptional() != optional) { + continue; + } + if (layers != null) { + List storedLayers = new ArrayList(); + for (WRobotNexusTestResult wRobot : vNexusResult.getwRobotNexusTestResults()) { + storedLayers.add(wRobot.getBlueprintLayer()); + } + if (!new HashSet<>(storedLayers).equals(new HashSet<>(layers))) { + continue; + } + } + return vNexusResult; + } catch (HttpException ex) { + LOGGER.warn(EELFLoggerDelegate.auditLogger, + "Error when trying to retrieve results. " + UserUtils.getStackTrace(ex)); + continue; } - }}; + } + return null; } - public String getBaseUrl() { - return this.baseurl; + public ValidationNexusTestResult getLastResultBasedOnOutcome(@Nonnull String name, @Nonnull String version, + @Nonnull String siloText, Boolean allLayers, Boolean optional, boolean outcome) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException, ParseException, NullPointerException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version; + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get last result based on outcome"); + WebResource webResource = this.client.resource(nexusUrl + "/"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + throw new HttpException("Could not retrieve last result based on outcome from Nexus. HTTP error code : " + + response.getStatus() + " and message: " + response.getEntity(String.class)); + } + Document document = Jsoup.parse(response.getEntity(String.class)); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tbody").get(0).getElementsByTag("tr"); + elements = elements.subList(2, elements.size()); + if (elements.size() < 1) { + return null; + } + DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + Collections.sort(elements, new Comparator() { + @Override + public int compare(Element element1, Element element2) { + try { + return dateFormat.parse(element2.getElementsByTag("td").get(1).text()) + .compareTo(dateFormat.parse(element1.getElementsByTag("td").get(1).text())); + } catch (ParseException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when parsing date. " + UserUtils.getStackTrace(e)); + return 0; + } + } + }); + for (Element element : elements) { + try { + String elementTimestamp = element.getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + elementTimestamp = elementTimestamp.substring(0, elementTimestamp.length() - 1); + ValidationNexusTestResult vNexusResult = this.getResult(name, version, siloText, elementTimestamp); + if (vNexusResult.getResult() != outcome) { + continue; + } + if (optional != null && vNexusResult.getOptional() != optional) { + continue; + } + if (allLayers != null && vNexusResult.getAllLayers() != allLayers) { + continue; + } + return vNexusResult; + } catch (HttpException ex) { + LOGGER.warn(EELFLoggerDelegate.auditLogger, + "Error when trying to retrieve results. " + UserUtils.getStackTrace(ex)); + continue; + } + } + return null; } - public List getRobotTestResults() throws ClientHandlerException, UniformInterfaceException, - JsonParseException, JsonMappingException, IOException, KeyManagementException, NoSuchAlgorithmException { - List listOfwrappers = new ArrayList(); + public List getWRobotTestResults(@Nonnull String name, @Nonnull String version, + @Nonnull String siloText, @Nonnull String timestamp) + throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, + IOException, KeyManagementException, NoSuchAlgorithmException { + String nexusUrl = this.baseurl + "/" + siloText + "/" + name + "/" + version + "/" + timestamp + "/results"; + List listOfwrappers = new ArrayList(); LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get the blueprint layers"); - setProperties(); - WebResource webResource = this.client.resource(this.baseurl + "/"); + WebResource webResource = this.client.resource(nexusUrl + "/"); LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); ClientResponse response = webResource.get(ClientResponse.class); if (response.getStatus() != 200) { @@ -135,31 +388,38 @@ public final class NexusExecutorClient { + response.getStatus() + " and message: " + response.getEntity(String.class)); } Document document = Jsoup.parse(response.getEntity(String.class)); - List elements = - document.getElementsByTag("body").get(0).getElementsByTag("table").get(0).getElementsByTag("tr"); + List elements = document.getElementsByTag("body").get(0).getElementsByTag("table").get(0) + .getElementsByTag("tr"); for (int i = 2; i < elements.size(); i++) { - String layer = elements.get(i).getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); - layer = layer.substring(0, layer.length() - 1); - List robotTestResults = getResultsOfALayer(this.baseurl + "/" + layer); - WrapperRobotTestResult wrapper = new WrapperRobotTestResult(); - wrapper.setBlueprintLayer(BlueprintLayer.valueOf(layer.substring(0, 1).toUpperCase() + layer.substring(1))); - wrapper.setRobotTestResults(robotTestResults); - listOfwrappers.add(wrapper); + try { + String layer = elements.get(i).getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + layer = layer.substring(0, layer.length() - 1); + if (layer.contains("test")) { + continue; + } + List robotTestResults = getRobotTestResults(nexusUrl + "/" + layer); + WRobotNexusTestResult wrapper = new WRobotNexusTestResult(); + wrapper.setBlueprintLayer(BlueprintLayer.valueOf(layer)); + wrapper.setRobotTestResults(robotTestResults); + listOfwrappers.add(wrapper); + } catch (HttpException | IllegalArgumentException ex) { + LOGGER.warn(EELFLoggerDelegate.auditLogger, "Exception occured while retrieving robot results"); + continue; + } } return listOfwrappers; } - private List getResultsOfALayer(String resultsUrl) + private List getRobotTestResults(String resultsUrl) throws ClientHandlerException, UniformInterfaceException, JsonParseException, JsonMappingException, IOException, KeyManagementException, NoSuchAlgorithmException { - List robotTestResults = new ArrayList(); - LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get Robot Test Results"); - setProperties(); + List rTestResults = new ArrayList(); + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get test suites results"); WebResource webResource = this.client.resource(resultsUrl + "/"); LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); ClientResponse response = webResource.get(ClientResponse.class); if (response.getStatus() != 200) { - throw new HttpException("Could not retrieve robot test results from Nexus. HTTP error code : " + throw new HttpException("Could not retrieve test suites results from Nexus. HTTP error code : " + response.getStatus() + " and message: " + response.getEntity(String.class)); } Document document = Jsoup.parse(response.getEntity(String.class)); @@ -172,7 +432,7 @@ public final class NexusExecutorClient { LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); response = webResource.get(ClientResponse.class); if (response.getStatus() != 200) { - throw new HttpException("Could not retrieve robot test result from Nexus. HTTP error code : " + throw new HttpException("Could not retrieve test suite result from Nexus. HTTP error code : " + response.getStatus() + " and message: " + response.getEntity(String.class)); } String result = response.getEntity(String.class); @@ -183,21 +443,86 @@ public final class NexusExecutorClient { mapper.setSerializationInclusion(Include.NON_NULL); RobotTestResult robotTestResult = mapper.readValue(xmlJSONObj.toString(), RobotTestResult.class); robotTestResult.setName(testSuiteName); - robotTestResults.add(robotTestResult); + rTestResults.add(robotTestResult); + } + return rTestResults; + } + + private boolean determineResult(List wTestResults) { + boolean result = true; + for (WRobotNexusTestResult wTestResult : wTestResults) { + for (RobotTestResult robotTestResult : wTestResult.getRobotTestResults()) { + for (Status status : robotTestResult.getRobot().getStatistics().getTotal().getStat()) { + if (status.getContent().trim().equals("All Tests") && status.getFail() > 0) { + result = false; + } + } + } + } + return result; + } + + private List findLastElementsByDate(List elements, int noOfLastElements) { + if (elements.size() <= noOfLastElements) { + return elements; } - return robotTestResults; + DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + Collections.sort(elements, new Comparator() { + @Override + public int compare(Element element1, Element element2) { + try { + return dateFormat.parse(element2.getElementsByTag("td").get(1).text()) + .compareTo(dateFormat.parse(element1.getElementsByTag("td").get(1).text())); + } catch (ParseException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when parsing date. " + UserUtils.getStackTrace(e)); + return 0; + } + } + }); + return elements.subList(0, noOfLastElements); } - private void setProperties() throws NoSuchAlgorithmException, KeyManagementException { - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, this.trustAll, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); - // Install the all-trusting host verifier - HttpsURLConnection.setDefaultHostnameVerifier(this.hostnameVerifier); - DefaultClientConfig config = new DefaultClientConfig(); - Map properties = config.getProperties(); - HTTPSProperties httpsProperties = new HTTPSProperties((str, sslSession) -> true, sslContext); - properties.put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, httpsProperties); + private Element findElementByTimestamp(List elements, String timestamp) { + for (Element element : elements) { + String elementTimestamp = element.getElementsByTag("td").get(0).getElementsByTag("a").get(0).text(); + elementTimestamp = elementTimestamp.substring(0, elementTimestamp.length() - 1); + if (elementTimestamp.equals(timestamp)) { + return element; + } + } + return null; } + private List findElementsBasedOnDate(List elements, Date date) throws ParseException { + DateFormat formatTime = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + DateFormat formatNoTime = new SimpleDateFormat("EEE MMM dd zzz yyyy", Locale.US); + List desiredElements = new ArrayList(); + for (Element element : elements) { + String lastModified = element.getElementsByTag("td").get(1).text(); + if (formatNoTime.format(formatTime.parse(lastModified)).compareTo(formatNoTime.format(date)) == 0) { + desiredElements.add(element); + } + } + return desiredElements; + } + + private TestInfoYaml getTestInfo(String timestampUrl) throws JsonParseException, JsonMappingException, IOException { + LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get test info"); + WebResource webResource = this.client.resource(timestampUrl + "/results/test_info.yaml"); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString()); + ClientResponse response = webResource.get(ClientResponse.class); + if (response.getStatus() != 200) { + return null; + } + String testInfo = response.getEntity(String.class); + ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); + Object obj = yamlReader.readValue(testInfo, Object.class); + 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); + ObjectMapper jsonWriter = new ObjectMapper(); + return mapper.readValue(jsonWriter.writeValueAsString(obj), TestInfoYaml.class); + } } diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/TestInfoYaml.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/TestInfoYaml.java new file mode 100644 index 0000000..94500ef --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/TestInfoYaml.java @@ -0,0 +1,70 @@ +/* + * 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 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 TestInfoYaml { + + @JsonProperty("test_info") + private test_info test_info; + + public TestInfoYaml() { + + } + + public test_info gettest_info() { + return this.test_info; + } + + public void settest_info(test_info test_info) { + this.test_info = test_info; + } + + public class test_info { + + @JsonProperty("layer") + private String layer; + + @JsonProperty("optional") + private Boolean optional; + + public test_info() { + + } + + public String getLayer() { + return this.layer; + } + + public void setLayer(String layer) { + this.layer = layer; + } + + public Boolean getOptional() { + return this.optional; + } + + public void setOptional(Boolean optional) { + this.optional = optional; + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/ValidationNexusTestResult.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/ValidationNexusTestResult.java new file mode 100644 index 0000000..59a3592 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/ValidationNexusTestResult.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; + +public class ValidationNexusTestResult { + + private int resultId; + + private String blueprintName; + + private String version; + + private String silo; + + private Boolean allLayers; + + private Boolean optional; + + private boolean result; + + private String dateOfStorage; + + private String timestamp; + + private String submissionId; + + private List wRobotNexusTestResults; + + public ValidationNexusTestResult() { + + } + + public Integer getResultId() { + return this.resultId; + } + + public void setResultId(Integer resultId) { + this.resultId = resultId; + } + + public String getBlueprintName() { + return this.blueprintName; + } + + public void setBlueprintName(String blueprintName) { + this.blueprintName = blueprintName; + } + + public String getVersion() { + return this.version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getSilo() { + return this.silo; + } + + public void setSilo(String silo) { + this.silo = silo; + } + + public Boolean getAllLayers() { + return this.allLayers; + } + + public void setAllLayers(Boolean allLayers) { + this.allLayers = allLayers; + } + + public Boolean getOptional() { + return this.optional; + } + + public void setOptional(Boolean optional) { + this.optional = optional; + } + + public boolean getResult() { + return this.result; + } + + public void setResult(boolean result) { + this.result = result; + } + + public String getDateOfStorage() { + return this.dateOfStorage; + } + + public void setDateOfStorage(String dateOfStorage) { + this.dateOfStorage = dateOfStorage; + } + + public String getTimestamp() { + return this.timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public String getSubmissionId() { + return this.submissionId; + } + + public void setSubmissionId(String submissionId) { + this.submissionId = submissionId; + } + + public List getwRobotNexusTestResults() { + return this.wRobotNexusTestResults; + } + + public void setwRobotNexusTestResults(List wRobotNexusTestResults) { + this.wRobotNexusTestResults = wRobotNexusTestResults; + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WrapperRobotTestResult.java b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WRobotNexusTestResult.java similarity index 65% rename from ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WrapperRobotTestResult.java rename to ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WRobotNexusTestResult.java index 30e6721..7cfdbd8 100644 --- a/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WrapperRobotTestResult.java +++ b/ui/src/main/java/org/akraino/validation/ui/client/nexus/resources/WRobotNexusTestResult.java @@ -19,30 +19,30 @@ import java.util.List; import org.akraino.validation.ui.data.BlueprintLayer; -public class WrapperRobotTestResult { +public class WRobotNexusTestResult { - private BlueprintLayer layer; + private BlueprintLayer blueprintLayer; - private List testResults; + private List robotTestResult; - public WrapperRobotTestResult() { + public WRobotNexusTestResult() { } public BlueprintLayer getBlueprintLayer() { - return this.layer; + return this.blueprintLayer; } - public void setBlueprintLayer(BlueprintLayer layer) { - this.layer = layer; + public void setBlueprintLayer(BlueprintLayer blueprintLayer) { + this.blueprintLayer = blueprintLayer; } public List getRobotTestResults() { - return this.testResults; + return this.robotTestResult; } - public void setRobotTestResults(List testResults) { - this.testResults = testResults; + public void setRobotTestResults(List robotTestResult) { + this.robotTestResult = robotTestResult; } } diff --git a/ui/src/main/java/org/akraino/validation/ui/conf/UiUtils.java b/ui/src/main/java/org/akraino/validation/ui/conf/ExecutorServiceInitializer.java similarity index 72% rename from ui/src/main/java/org/akraino/validation/ui/conf/UiUtils.java rename to ui/src/main/java/org/akraino/validation/ui/conf/ExecutorServiceInitializer.java index 7ef8234..bfe4fc9 100644 --- a/ui/src/main/java/org/akraino/validation/ui/conf/UiUtils.java +++ b/ui/src/main/java/org/akraino/validation/ui/conf/ExecutorServiceInitializer.java @@ -22,23 +22,30 @@ import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -public class UiUtils { +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ExecutorServiceInitializer { private static final int QUEUE_CAPACITY = 500; - private static final int EXECUTOR_SIZE = 20; // the number of threads to keep in the pool, even if + private static final int EXECUTOR_SIZE = 30; // the number of threads to keep in the pool, even if // they are idle, unless allowCoreThreadTimeOut is // set - private static final int EXECUTOR_MAX_SIZE = 20; // the maximum number of threads to allow in the pool - private static final int KEEPALIVE_TIME = 20; // when the number of threads is greater than the + private static final int EXECUTOR_MAX_SIZE = 30; // the maximum number of threads to allow in the pool + private static final int KEEPALIVE_TIME = 30; // when the number of threads is greater than the // core, this is the maximum time that excess idle // threads will wait for new tasks before // terminating. - private static final PriorityBlockingQueue BLOCKING_QUEUE = - new PriorityBlockingQueue(QUEUE_CAPACITY, new CFRunnableComparator()); - public static ExecutorService executorService = - new ThreadPoolExecutor(EXECUTOR_SIZE, EXECUTOR_MAX_SIZE, KEEPALIVE_TIME, TimeUnit.SECONDS, BLOCKING_QUEUE); + private static final PriorityBlockingQueue BLOCKING_QUEUE = new PriorityBlockingQueue( + QUEUE_CAPACITY, new CFRunnableComparator()); + private static ExecutorService executorService = new ThreadPoolExecutor(EXECUTOR_SIZE, EXECUTOR_MAX_SIZE, + KEEPALIVE_TIME, TimeUnit.SECONDS, BLOCKING_QUEUE); - public static final String NEXUS_URL = "https://nexus.akraino.org/content/sites/logs"; + @Bean(name = "executorService") + public ExecutorService getExecutorService() { + return this.executorService; + } private static class CFRunnableComparator implements Comparator { @Override diff --git a/ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppConfig.java b/ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppConfig.java index bb139f6..3317260 100644 --- a/ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppConfig.java +++ b/ui/src/main/java/org/akraino/validation/ui/conf/ExternalAppConfig.java @@ -31,6 +31,7 @@ import org.onap.portalsdk.core.logging.format.AppMessagesEnum; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.objectcache.AbstractCacheManager; import org.onap.portalsdk.core.onboarding.util.CipherUtil; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; import org.onap.portalsdk.core.service.DataAccessService; import org.onap.portalsdk.core.util.CacheManager; import org.onap.portalsdk.core.util.SystemProperties; @@ -54,12 +55,12 @@ import com.mchange.v2.c3p0.ComboPooledDataSource; @Configuration @EnableWebMvc -@ComponentScan(basePackages = {"org.akraino", "org.onap"}) -@PropertySource(value = {"${container.classpath:}/WEB-INF/conf/app/test.properties"}, ignoreResourceNotFound = true) +@ComponentScan(basePackages = { "org.akraino", "org.onap" }) +@PropertySource(value = { "${container.classpath:}/WEB-INF/conf/app/test.properties" }, ignoreResourceNotFound = true) @Profile("src") @EnableAsync @EnableScheduling -@Import({MusicSessionConfig.class}) +@Import({ MusicSessionConfig.class }) public class ExternalAppConfig extends AppConfig implements Configurable { private RegistryAdapter schedulerRegistryAdapter; @@ -112,9 +113,10 @@ public class ExternalAppConfig extends AppConfig implements Configurable { ComboPooledDataSource dataSource = new ComboPooledDataSource(); try { dataSource.setDriverClass(SystemProperties.getProperty(SystemProperties.DB_DRIVER)); - dataSource.setJdbcUrl("jdbc:mariadb://" + System.getenv("DB_CONNECTION_URL")); + dataSource.setJdbcUrl("jdbc:mariadb://" + System.getenv("DB_IP_PORT") + "/" + + PortalApiProperties.getProperty("akraino_database_name")); dataSource.setUser(SystemProperties.getProperty(SystemProperties.DB_USERNAME)); - String password = System.getenv("MARIADB_ROOT_PASSWORD"); + String password = System.getenv("MARIADB_AKRAINO_PASSWORD"); if (SystemProperties.containsProperty(SystemProperties.DB_ENCRYPT_FLAG)) { String encryptFlag = SystemProperties.getProperty(SystemProperties.DB_ENCRYPT_FLAG); if (encryptFlag != null && encryptFlag.equalsIgnoreCase("true")) { @@ -123,9 +125,9 @@ public class ExternalAppConfig extends AppConfig implements Configurable { } dataSource.setPassword(password); dataSource - .setMinPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MIN_POOL_SIZE))); + .setMinPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MIN_POOL_SIZE))); dataSource - .setMaxPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MAX_POOL_SIZE))); + .setMaxPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MAX_POOL_SIZE))); dataSource.setIdleConnectionTestPeriod( Integer.parseInt(SystemProperties.getProperty(SystemProperties.IDLE_CONNECTION_TEST_PERIOD))); dataSource.setTestConnectionOnCheckout(getConnectionOnCheckout()); @@ -134,11 +136,11 @@ public class ExternalAppConfig extends AppConfig implements Configurable { LOGGER.error(EELFLoggerDelegate.errorLogger, "Error initializing database, verify database settings in properties file: " + UserUtils.getStackTrace(e), - AlarmSeverityEnum.CRITICAL); + AlarmSeverityEnum.CRITICAL); LOGGER.error(EELFLoggerDelegate.debugLogger, "Error initializing database, verify database settings in properties file: " + UserUtils.getStackTrace(e), - AlarmSeverityEnum.CRITICAL); + AlarmSeverityEnum.CRITICAL); // Raise an alarm that opening a connection to the database failed. LOGGER.logEcompError(AppMessagesEnum.BeDaoSystemError); throw e; @@ -161,13 +163,13 @@ public class ExternalAppConfig extends AppConfig implements Configurable { /** * Adds request interceptors to the specified registry by calling - * {@link AppConfig#addInterceptors(InterceptorRegistry)}, but excludes - * certain paths from the session timeout interceptor. + * {@link AppConfig#addInterceptors(InterceptorRegistry)}, but excludes certain + * paths from the session timeout interceptor. */ @Override public void addInterceptors(InterceptorRegistry registry) { super.setExcludeUrlPathsForSessionTimeout("/login_external", "*/login_external.htm", "login", "/login.htm", - "/api*", "/single_signon.htm", "/single_signon"); + "/api*", "/single_signon.htm", "/single_signon", "logout", "/logout.htm"); super.addInterceptors(registry); } @@ -182,8 +184,8 @@ public class ExternalAppConfig extends AppConfig implements Configurable { } /** - * Creates and returns a new instance of a {@link SchedulerFactoryBean} - * and populates it with triggers. + * Creates and returns a new instance of a {@link SchedulerFactoryBean} and + * populates it with triggers. * * @return New instance of {@link SchedulerFactoryBean} * @throws Exception @@ -214,9 +216,8 @@ public class ExternalAppConfig extends AppConfig implements Configurable { } /** - * Gets the value of the property - * {@link SystemProperties#PREFERRED_TEST_QUERY}; defaults to "Select 1" - * if the property is not defined. + * Gets the value of the property {@link SystemProperties#PREFERRED_TEST_QUERY}; + * defaults to "Select 1" if the property is not defined. * * @return String value that is a SQL query */ @@ -237,8 +238,8 @@ public class ExternalAppConfig extends AppConfig implements Configurable { /** * Gets the value of the property - * {@link SystemProperties#TEST_CONNECTION_ON_CHECKOUT}; defaults to true - * if the property is not defined. + * {@link SystemProperties#TEST_CONNECTION_ON_CHECKOUT}; defaults to true if the + * property is not defined. * * @return Boolean value */ @@ -246,8 +247,8 @@ public class ExternalAppConfig extends AppConfig implements Configurable { // Default to true, always test connection boolean testConnectionOnCheckout = true; if (SystemProperties.containsProperty(SystemProperties.TEST_CONNECTION_ON_CHECKOUT)) { - testConnectionOnCheckout = - Boolean.valueOf(SystemProperties.getProperty(SystemProperties.TEST_CONNECTION_ON_CHECKOUT)); + testConnectionOnCheckout = Boolean + .valueOf(SystemProperties.getProperty(SystemProperties.TEST_CONNECTION_ON_CHECKOUT)); LOGGER.debug(EELFLoggerDelegate.debugLogger, "getConnectionOnCheckout: property key {} value is {}", SystemProperties.TEST_CONNECTION_ON_CHECKOUT, testConnectionOnCheckout); } else { diff --git a/ui/src/main/java/org/akraino/validation/ui/conf/UiInitializer.java b/ui/src/main/java/org/akraino/validation/ui/conf/UiInitializer.java new file mode 100644 index 0000000..febafe1 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/conf/UiInitializer.java @@ -0,0 +1,78 @@ +/* + * 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.conf; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.client.urlconnection.HTTPSProperties; + +@Component +public class UiInitializer { + + // Create all-trusting host name verifier + private final HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + // Create a trust manager that does not validate certificate chains + private final TrustManager[] trustAll = new TrustManager[] { new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; // Not relevant. + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { + // Do nothing. Just allow them all. + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { + // Do nothing. Just allow them all. + } + } }; + + @EventListener(ContextRefreshedEvent.class) + public void setHttpProperties() throws NoSuchAlgorithmException, KeyManagementException { + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, this.trustAll, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + // Install the all-trusting host verifier + HttpsURLConnection.setDefaultHostnameVerifier(this.hostnameVerifier); + DefaultClientConfig config = new DefaultClientConfig(); + Map properties = config.getProperties(); + HTTPSProperties httpsProperties = new HTTPSProperties((str, sslSession) -> true, sslContext); + properties.put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, httpsProperties); + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/conf/ValidationNexusTestResultsGetter.java b/ui/src/main/java/org/akraino/validation/ui/conf/ValidationNexusTestResultsGetter.java new file mode 100644 index 0000000..769549a --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/conf/ValidationNexusTestResultsGetter.java @@ -0,0 +1,110 @@ +/* + * 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.conf; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; + +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.data.Lab; +import org.akraino.validation.ui.service.DbResultAdapter; +import org.akraino.validation.ui.service.IntegratedResultService; +import org.akraino.validation.ui.service.utils.PrioritySupplier; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +@Component +public class ValidationNexusTestResultsGetter implements ApplicationListener { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate + .getLogger(ValidationNexusTestResultsGetter.class); + + @Autowired + IntegratedResultService integratedService; + + @Autowired + DbResultAdapter dbAdapter; + + @Override + public void onApplicationEvent(final ContextRefreshedEvent event) { + ApplicationContext context = new AnnotationConfigApplicationContext(ExecutorServiceInitializer.class); + ExecutorService service = (ExecutorService) context.getBean("executorService"); + ValidationNexusTestResultsGetterExecution task = new ValidationNexusTestResultsGetterExecution(); + CompletableFuture>> completableFuture = CompletableFuture + .supplyAsync(new PrioritySupplier<>(1, task::execute), service); + completableFuture.thenAcceptAsync(results -> this.callbackNotify(results)); + } + + private void callbackNotify(List> results) { + try { + for (List result : results) { + + LOGGER.debug(EELFLoggerDelegate.debugLogger, + "Validation test results retrieved from nexus with size : " + result.size()); + dbAdapter.deleteUnreferencedEntries(result); + dbAdapter.storeResultInDb(result); + } + Thread.sleep(Integer.valueOf(PortalApiProperties.getProperty("thread_sleep"))); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error in callback notification. " + UserUtils.getStackTrace(e)); + } + // Trigger the next retrieval of results + ApplicationContext context = new AnnotationConfigApplicationContext(ExecutorServiceInitializer.class); + ExecutorService service = (ExecutorService) context.getBean("executorService"); + ValidationNexusTestResultsGetterExecution task = new ValidationNexusTestResultsGetterExecution(); + CompletableFuture>> completableFuture = CompletableFuture + .supplyAsync(new PrioritySupplier<>(1, task::execute), service); + completableFuture.thenAcceptAsync(newResults -> this.callbackNotify(newResults)); + } + + private class ValidationNexusTestResultsGetterExecution { + + public ValidationNexusTestResultsGetterExecution() { + } + + public List> execute() { + List> results = new ArrayList>(); + try { + for (Lab lab : integratedService.getLabsFromNexus()) { + for (String blueprintName : integratedService.getBlueprintNamesOfLabFromNexus(lab)) { + for (String version : integratedService.getBlueprintVersionsFromNexus(blueprintName, lab)) { + LOGGER.debug(EELFLoggerDelegate.debugLogger, + "Trying to retrieve validation test result from nexus for: blueprint name: " + + blueprintName + ", version: " + version + " and lab: " + lab.name()); + results.add(integratedService.getResultsFromNexus(blueprintName, version, lab, + Integer.valueOf(PortalApiProperties.getProperty("no_last_timestamps")))); + } + } + } + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving Nexus results. " + UserUtils.getStackTrace(e)); + } + return results; + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintController.java b/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintController.java index fdc6449..091738a 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintController.java @@ -31,7 +31,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/blueprint") +@RequestMapping("/api/v1/blueprint") public class BlueprintController extends RestrictedBaseController { private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(BlueprintController.class); diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintInstanceForValidationController.java b/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintInstanceForValidationController.java index 749fb75..ab2afd2 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintInstanceForValidationController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/BlueprintInstanceForValidationController.java @@ -31,11 +31,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/blueprintInstanceForValidation") +@RequestMapping("/api/v1/blueprintinstanceforvalidation") public class BlueprintInstanceForValidationController extends RestrictedBaseController { - private static final EELFLoggerDelegate LOGGER = - EELFLoggerDelegate.getLogger(BlueprintInstanceForValidationController.class); + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate + .getLogger(BlueprintInstanceForValidationController.class); @Autowired BlueprintInstanceForValidationService service; @@ -44,7 +44,7 @@ public class BlueprintInstanceForValidationController extends RestrictedBaseCont super(); } - @RequestMapping(value = {"/"}, method = RequestMethod.GET) + @RequestMapping(value = { "/" }, method = RequestMethod.GET) public ResponseEntity> getBlueprintInstancesForValidation() { try { return new ResponseEntity<>(service.getBlueprintInstancesForValidation(), HttpStatus.OK); diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/JenkinsJobNotificationController.java b/ui/src/main/java/org/akraino/validation/ui/controller/JenkinsJobNotificationController.java index 79bedb1..35cea69 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/JenkinsJobNotificationController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/JenkinsJobNotificationController.java @@ -29,20 +29,20 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/jenkinsJobNotification") +@RequestMapping("/api/v1/jenkinsjobnotification") public class JenkinsJobNotificationController extends RestrictedBaseController { @Autowired JenkinsJobNotificationService service; - private static final EELFLoggerDelegate LOGGER = - EELFLoggerDelegate.getLogger(JenkinsJobNotificationController.class); + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate + .getLogger(JenkinsJobNotificationController.class); public JenkinsJobNotificationController() { super(); } - @RequestMapping(value = {"/"}, method = RequestMethod.POST) + @RequestMapping(value = { "/" }, method = RequestMethod.POST) public ResponseEntity handle(@RequestBody JnksJobNotify jnksJobNotify) { try { service.handle(jnksJobNotify); diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/ModelsViewsController.java b/ui/src/main/java/org/akraino/validation/ui/controller/ModelsViewsController.java index 430f169..cc9cec2 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/ModelsViewsController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/ModelsViewsController.java @@ -16,6 +16,9 @@ package org.akraino.validation.ui.controller; +import java.util.HashMap; +import java.util.Map; + import javax.servlet.http.HttpServletRequest; import org.onap.portalsdk.core.controller.RestrictedBaseController; @@ -32,21 +35,52 @@ public class ModelsViewsController extends RestrictedBaseController { super(); } - @RequestMapping(value = {"/newSubmission"}, method = RequestMethod.GET) + @RequestMapping(value = { "/newsubmission" }, method = RequestMethod.GET) public ModelAndView newSubmission(HttpServletRequest request) { final String defaultViewName = null; return new ModelAndView(defaultViewName); } - @RequestMapping(value = {"/committedSubmissions"}, method = RequestMethod.GET) + @RequestMapping(value = { "/committedsubmissions" }, method = RequestMethod.GET) public ModelAndView committedSubmissions(HttpServletRequest request) { final String defaultViewName = null; return new ModelAndView(defaultViewName); } - @RequestMapping(value = {"/getBySubmissionId"}, method = RequestMethod.GET) - public ModelAndView getBySubmissionId(HttpServletRequest request) { + @RequestMapping(value = { "/getmostrecent" }, method = RequestMethod.GET) + public ModelAndView getMostrecent(HttpServletRequest request) { + final String defaultViewName = null; + return new ModelAndView(defaultViewName); + } + + @RequestMapping(value = { "/getbytimestamp" }, method = RequestMethod.GET) + public ModelAndView getByTimestamp(HttpServletRequest request) { + final String defaultViewName = null; + return new ModelAndView(defaultViewName); + } + + @RequestMapping(value = { "/getlastrun" }, method = RequestMethod.GET) + public ModelAndView getLastRun(HttpServletRequest request) { + final String defaultViewName = null; + return new ModelAndView(defaultViewName); + } + + @RequestMapping(value = { "/getbasedondate" }, method = RequestMethod.GET) + public ModelAndView getBasedOnDate(HttpServletRequest request) { + final String defaultViewName = null; + return new ModelAndView(defaultViewName); + } + + @RequestMapping(value = { "/validationresults" }, method = RequestMethod.GET) + public ModelAndView validationResults(HttpServletRequest request) { final String defaultViewName = null; return new ModelAndView(defaultViewName); } + + @RequestMapping(value = { "/logout.htm" }, method = RequestMethod.GET) + public ModelAndView login() { + Map model = new HashMap<>(); + return new ModelAndView("logout", "model", model); + } + } diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/ResultController.java b/ui/src/main/java/org/akraino/validation/ui/controller/ResultController.java new file mode 100644 index 0000000..f9c205a --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/controller/ResultController.java @@ -0,0 +1,174 @@ +/* + * 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.controller; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Set; + +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.data.BlueprintLayer; +import org.akraino.validation.ui.data.Lab; +import org.akraino.validation.ui.service.DbResultAdapter; +import org.akraino.validation.ui.service.IntegratedResultService; +import org.onap.portalsdk.core.controller.RestrictedBaseController; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping("/api/v1/results") +public class ResultController extends RestrictedBaseController { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ResultController.class); + + @Autowired + IntegratedResultService resultService; + + @Autowired + DbResultAdapter dbAdapter; + + public ResultController() { + super(); + } + + @RequestMapping(value = { "/getlabs/" }, method = RequestMethod.GET) + public ResponseEntity> getLabs() { + try { + return new ResponseEntity<>(resultService.getLabsFromDb(), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, "Error when retrieving labs. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getblueprintnamesoflab/{lab}" }, method = RequestMethod.GET) + public ResponseEntity> getBlueprintNamesOfLab(@PathVariable("lab") Lab lab) { + try { + return new ResponseEntity<>(resultService.getBlueprintNamesOfLabFromDb(lab), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving blueprint names of a lab. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getblueprintversions/{name}/{lab}" }, method = RequestMethod.GET) + public ResponseEntity> getBlueprintVersions(@PathVariable("name") String name, + @PathVariable("lab") Lab lab) { + try { + return new ResponseEntity<>(resultService.getBlueprintVersionsFromDb(name, lab), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving blueprint versions. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getbysubmissionid/{id}" }, method = RequestMethod.GET) + public ResponseEntity getBySubmissionId(@PathVariable("id") String submissionId) { + try { + return new ResponseEntity<>(resultService.getResults(submissionId), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving results using submission id. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getmostrecent/{name}/{version}/{lab}" }, method = RequestMethod.GET) + public ResponseEntity> getMostRecent(@PathVariable("name") String name, + @PathVariable("version") String version, @PathVariable("lab") Lab lab) { + try { + return new ResponseEntity<>(dbAdapter.readResultFromDb(name, version, lab, null, null, null, null), + HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving most recent results. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getbytimestamp/{lab}/{name}/{version}/{timestamp}" }, method = RequestMethod.GET) + public ResponseEntity getByTimestamp(@PathVariable("lab") Lab lab, + @PathVariable("name") String name, @PathVariable("version") String version, + @PathVariable("timestamp") String timestamp) { + try { + return new ResponseEntity<>(resultService.getResult(name, version, lab, timestamp), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving results using timestamp data. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { + "/getlastrun/{lab}/{name}/{version}/{allLayers}/{optional}/{outcome}" }, method = RequestMethod.GET) + public ResponseEntity getLastRun(@PathVariable("lab") Lab lab, + @PathVariable("name") String name, @PathVariable("version") String version, + @PathVariable("allLayers") Boolean allLayers, @PathVariable("optional") Boolean optional, + @PathVariable("outcome") boolean outcome) { + try { + return new ResponseEntity<>( + resultService.getLastResultBasedOnOutcome(name, version, lab, allLayers, optional, outcome), + HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving last result. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { + "/getlastrunoflayers/{lab}/{name}/{version}/{layers}/{optional}/{outcome}" }, method = RequestMethod.GET) + public ResponseEntity getLastRunOfLayers(@PathVariable("lab") Lab lab, + @PathVariable("name") String name, @PathVariable("version") String version, + @PathVariable("layers") List layers, @PathVariable("optional") Boolean optional, + @PathVariable("outcome") boolean outcome) { + try { + return new ResponseEntity<>( + resultService.getLastResultBasedOnOutcome(name, version, lab, layers, optional, outcome), + HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving last result. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/getbasedondate/{lab}/{name}/{version}/{date}" }, method = RequestMethod.GET) + public ResponseEntity> getBasedOnDate(@PathVariable("lab") Lab lab, + @PathVariable("name") String name, @PathVariable("version") String version, + @PathVariable("date") String date) { + try { + DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy"); + return new ResponseEntity<>( + resultService.getBasedOnDateFromNexus(name, version, lab, dateFormat.parse(date)), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when retrieving results based on date. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/ResultsController.java b/ui/src/main/java/org/akraino/validation/ui/controller/SiloController.java similarity index 66% rename from ui/src/main/java/org/akraino/validation/ui/controller/ResultsController.java rename to ui/src/main/java/org/akraino/validation/ui/controller/SiloController.java index a4b460d..18f4f72 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/ResultsController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/SiloController.java @@ -13,12 +13,13 @@ * implied. See the License for the specific language governing * permissions and limitations under the License. */ + package org.akraino.validation.ui.controller; import java.util.List; -import org.akraino.validation.ui.client.nexus.resources.WrapperRobotTestResult; -import org.akraino.validation.ui.service.ResultService; +import org.akraino.validation.ui.entity.LabSilo; +import org.akraino.validation.ui.service.SiloService; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.web.support.UserUtils; @@ -26,32 +27,30 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/results") -public class ResultsController extends RestrictedBaseController { +@RequestMapping("/api/v1/silo") +public class SiloController extends RestrictedBaseController { - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ResultsController.class); + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(SiloController.class); @Autowired - ResultService service; + SiloService service; - public ResultsController() { + public SiloController() { super(); } - @RequestMapping(value = {"/getBySubmissionId/{id}"}, method = RequestMethod.GET) - public ResponseEntity> getByBlueprintId(@PathVariable("id") String submissionId) { + @RequestMapping(value = { "/" }, method = RequestMethod.GET) + public ResponseEntity> getSilos() { try { - return new ResponseEntity<>(service.getRobotTestResults(submissionId), HttpStatus.OK); + return new ResponseEntity<>(service.getSilos(), HttpStatus.OK); } catch (Exception e) { LOGGER.error(EELFLoggerDelegate.errorLogger, - "Error when retrieving results. " + UserUtils.getStackTrace(e)); + "Error when trying to get lab silos. " + UserUtils.getStackTrace(e)); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } - } 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 fb6f8e0..49215b1 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 @@ -17,8 +17,8 @@ package org.akraino.validation.ui.controller; import java.util.List; -import org.akraino.validation.ui.entity.Submission; -import org.akraino.validation.ui.service.SubmissionService; +import org.akraino.validation.ui.data.SubmissionData; +import org.akraino.validation.ui.service.DbSubmissionAdapter; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.web.support.UserUtils; @@ -26,16 +26,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/submission") +@RequestMapping("/api/v1/submission") public class SubmissionController extends RestrictedBaseController { @Autowired - SubmissionService service; + DbSubmissionAdapter service; private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(SubmissionController.class); @@ -43,20 +44,30 @@ public class SubmissionController extends RestrictedBaseController { super(); } - @RequestMapping(value = {"/"}, method = RequestMethod.GET) - public ResponseEntity> getSubmissions() { + @RequestMapping(value = { "/" }, method = RequestMethod.GET) + public ResponseEntity> getSubmissions() { try { - return new ResponseEntity<>(service.getSubmissions(), HttpStatus.OK); + return new ResponseEntity<>(service.getSubmissionDatas(), HttpStatus.OK); } catch (Exception e) { LOGGER.error(EELFLoggerDelegate.errorLogger, "Get of submissions failed. " + UserUtils.getStackTrace(e)); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } - @RequestMapping(value = {"/"}, method = RequestMethod.POST) - public ResponseEntity postSubmission(@RequestBody Submission newSubmission) { + @RequestMapping(value = { "/{id}" }, method = RequestMethod.GET) + public ResponseEntity getSubmission(@PathVariable("id") String submissionId) { try { - return new ResponseEntity<>(service.saveSubmission(newSubmission), HttpStatus.OK); + return new ResponseEntity<>(service.getSubmissionData(submissionId), HttpStatus.OK); + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, "Get of submission failed. " + UserUtils.getStackTrace(e)); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + @RequestMapping(value = { "/" }, method = RequestMethod.POST) + public ResponseEntity postSubmission(@RequestBody SubmissionData submissionData) { + try { + return new ResponseEntity<>(service.saveSubmission(submissionData), HttpStatus.OK); } catch (Exception e) { LOGGER.error(EELFLoggerDelegate.errorLogger, "Post of submission failed. " + UserUtils.getStackTrace(e)); } diff --git a/ui/src/main/java/org/akraino/validation/ui/controller/TimeslotsController.java b/ui/src/main/java/org/akraino/validation/ui/controller/TimeslotsController.java index 0f4f8d1..f82c273 100644 --- a/ui/src/main/java/org/akraino/validation/ui/controller/TimeslotsController.java +++ b/ui/src/main/java/org/akraino/validation/ui/controller/TimeslotsController.java @@ -31,7 +31,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller -@RequestMapping("/api/timeslots") +@RequestMapping("/api/v1/timeslots") public class TimeslotsController extends RestrictedBaseController { private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(TimeslotsController.class); @@ -43,7 +43,7 @@ public class TimeslotsController extends RestrictedBaseController { super(); } - @RequestMapping(value = {"/"}, method = RequestMethod.GET) + @RequestMapping(value = { "/" }, method = RequestMethod.GET) public ResponseEntity> getTimeSlots() { try { return new ResponseEntity<>(service.getTimeslots(), HttpStatus.OK); diff --git a/ui/src/main/java/org/akraino/validation/ui/dao/LabDAO.java b/ui/src/main/java/org/akraino/validation/ui/dao/LabDAO.java index 918c73f..6929f5f 100644 --- a/ui/src/main/java/org/akraino/validation/ui/dao/LabDAO.java +++ b/ui/src/main/java/org/akraino/validation/ui/dao/LabDAO.java @@ -17,6 +17,7 @@ package org.akraino.validation.ui.dao; import java.util.List; +import org.akraino.validation.ui.data.Lab; import org.akraino.validation.ui.entity.LabInfo; public interface LabDAO { @@ -29,6 +30,8 @@ public interface LabDAO { LabInfo getLab(Integer labId); + LabInfo getLab(Lab lab); + void deleteLab(LabInfo lab); void deleteAll(); diff --git a/ui/src/main/java/org/akraino/validation/ui/dao/ValidationTestResultDAO.java b/ui/src/main/java/org/akraino/validation/ui/dao/ValidationTestResultDAO.java new file mode 100644 index 0000000..6325606 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/dao/ValidationTestResultDAO.java @@ -0,0 +1,47 @@ +/* + * 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.dao; + +import java.util.List; + +import org.akraino.validation.ui.entity.LabInfo; +import org.akraino.validation.ui.entity.Submission; +import org.akraino.validation.ui.entity.ValidationDbTestResult; + +public interface ValidationTestResultDAO { + + void saveOrUpdate(ValidationDbTestResult vResult); + + void merge(ValidationDbTestResult vResult); + + List getValidationTestResults(); + + ValidationDbTestResult getValidationTestResult(Integer resultId); + + List getValidationTestResults(String blueprintName, String version, LabInfo labInfo, + Boolean allLayers, Boolean optional, Boolean outcome); + + ValidationDbTestResult getValidationTestResult(LabInfo labInfo, String timestamp); + + ValidationDbTestResult getValidationTestResult(Submission submission); + + void deleteValidationTestResult(LabInfo labInfo, String timestamp); + + void deleteValidationTestResult(ValidationDbTestResult vResult); + + void deleteAll(); + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/dao/WRobotTestResultDAO.java b/ui/src/main/java/org/akraino/validation/ui/dao/WRobotTestResultDAO.java new file mode 100644 index 0000000..e4a72b8 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/dao/WRobotTestResultDAO.java @@ -0,0 +1,41 @@ +/* + * 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.dao; + +import java.util.List; + +import org.akraino.validation.ui.entity.ValidationDbTestResult; +import org.akraino.validation.ui.entity.WRobotDbTestResult; + +public interface WRobotTestResultDAO { + + void saveOrUpdate(WRobotDbTestResult wResult); + + void merge(WRobotDbTestResult wResult); + + List getWRobotTestResults(); + + WRobotDbTestResult getWRobotTestResult(Integer wRobotResultId); + + WRobotDbTestResult getWRobotTestResult(String layer, ValidationDbTestResult vResult); + + List getWRobotTestResult(ValidationDbTestResult vResult); + + void deleteWRobotTestResult(Integer wRobotResultId); + + void deleteAll(); + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintDAOImpl.java index 771c327..a349bcf 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintDAOImpl.java @@ -17,6 +17,8 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.BlueprintDAO; import org.akraino.validation.ui.entity.Blueprint; import org.hibernate.Criteria; @@ -46,30 +48,34 @@ public class BlueprintDAOImpl implements BlueprintDAO { } @Override - public Blueprint getBlueprint(Integer blueprintId) { + public Blueprint getBlueprint(@Nonnull Integer blueprintId) { Criteria criteria = getSession().createCriteria(Blueprint.class); criteria.add(Restrictions.eq("id", String.valueOf(blueprintId))); return criteria.list() == null ? null : (Blueprint) criteria.list().get(0); } @Override - public void saveOrUpdate(Blueprint blueprint) { + public void saveOrUpdate(@Nonnull Blueprint blueprint) { getSession().saveOrUpdate(blueprint); + getSession().flush(); } @Override - public void merge(Blueprint blueprint) { + public void merge(@Nonnull Blueprint blueprint) { getSession().merge(blueprint); + getSession().flush(); } @Override - public void deleteBlueprint(Blueprint blueprint) { + public void deleteBlueprint(@Nonnull Blueprint blueprint) { getSession().delete(blueprint); + getSession().flush(); } @Override public void deleteAll() { if (getSession().createQuery("delete from Blueprint").executeUpdate() > 0) { + getSession().flush(); LOGGER.info(EELFLoggerDelegate.applicationLogger, "All blueprint entries are cleaned up"); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintInstanceForValidationDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintInstanceForValidationDAOImpl.java index 7c51b69..515f747 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintInstanceForValidationDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/BlueprintInstanceForValidationDAOImpl.java @@ -17,6 +17,8 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.BlueprintInstanceForValidationDAO; import org.akraino.validation.ui.entity.BlueprintInstanceForValidation; import org.hibernate.Criteria; @@ -30,8 +32,8 @@ import org.springframework.stereotype.Repository; @Repository public class BlueprintInstanceForValidationDAOImpl implements BlueprintInstanceForValidationDAO { - private static final EELFLoggerDelegate LOGGER = - EELFLoggerDelegate.getLogger(BlueprintInstanceForValidationDAOImpl.class); + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate + .getLogger(BlueprintInstanceForValidationDAOImpl.class); @Autowired private SessionFactory sessionFactory; @@ -47,25 +49,28 @@ public class BlueprintInstanceForValidationDAOImpl implements BlueprintInstanceF } @Override - public BlueprintInstanceForValidation getBlueprintInstanceForValidation(Integer instId) { + public BlueprintInstanceForValidation getBlueprintInstanceForValidation(@Nonnull Integer instId) { Criteria criteria = getSession().createCriteria(BlueprintInstanceForValidation.class); criteria.add(Restrictions.eq("id", String.valueOf(instId))); return criteria.list() == null ? null : (BlueprintInstanceForValidation) criteria.list().get(0); } @Override - public void saveOrUpdate(BlueprintInstanceForValidation blueprintInst) { + public void saveOrUpdate(@Nonnull BlueprintInstanceForValidation blueprintInst) { getSession().saveOrUpdate(blueprintInst); + getSession().flush(); } @Override - public void merge(BlueprintInstanceForValidation blueprintInst) { + public void merge(@Nonnull BlueprintInstanceForValidation blueprintInst) { getSession().merge(blueprintInst); + getSession().flush(); } @Override - public void deleteBlueprintInstanceForValidation(BlueprintInstanceForValidation blueprintInst) { + public void deleteBlueprintInstanceForValidation(@Nonnull BlueprintInstanceForValidation blueprintInst) { getSession().delete(blueprintInst); + getSession().flush(); } @Override @@ -73,6 +78,7 @@ public class BlueprintInstanceForValidationDAOImpl implements BlueprintInstanceF if (getSession().createQuery("delete from BlueprintInstanceForValidation").executeUpdate() > 0) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "All blueprint instances for validation entries are cleaned up"); + getSession().flush(); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/LabDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/LabDAOImpl.java index 3a383da..36512ab 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/LabDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/LabDAOImpl.java @@ -17,7 +17,10 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.LabDAO; +import org.akraino.validation.ui.data.Lab; import org.akraino.validation.ui.entity.LabInfo; import org.hibernate.Criteria; import org.hibernate.Session; @@ -46,31 +49,42 @@ public class LabDAOImpl implements LabDAO { } @Override - public LabInfo getLab(Integer labId) { + public LabInfo getLab(@Nonnull Integer labId) { Criteria criteria = getSession().createCriteria(LabInfo.class); criteria.add(Restrictions.eq("id", String.valueOf(labId))); return criteria.list() == null ? null : (LabInfo) criteria.list().get(0); } @Override - public void saveOrUpdate(LabInfo lab) { + public LabInfo getLab(@Nonnull Lab lab) { + Criteria criteria = getSession().createCriteria(LabInfo.class); + criteria.add(Restrictions.eq("lab", lab)); + return criteria.list() == null ? null : (LabInfo) criteria.list().get(0); + } + + @Override + public void saveOrUpdate(@Nonnull LabInfo lab) { getSession().saveOrUpdate(lab); + getSession().flush(); } @Override - public void merge(LabInfo lab) { + public void merge(@Nonnull LabInfo lab) { getSession().merge(lab); + getSession().flush(); } @Override - public void deleteLab(LabInfo lab) { + public void deleteLab(@Nonnull LabInfo lab) { getSession().delete(lab); + getSession().flush(); } @Override public void deleteAll() { if (getSession().createQuery("delete from Lab").executeUpdate() > 0) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "All lab entries are cleaned up"); + getSession().flush(); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/SiloDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/SiloDAOImpl.java index 3a347bd..8d3dffd 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/SiloDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/SiloDAOImpl.java @@ -17,6 +17,8 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.SiloDAO; import org.akraino.validation.ui.entity.LabSilo; import org.hibernate.Criteria; @@ -46,31 +48,35 @@ public class SiloDAOImpl implements SiloDAO { } @Override - public LabSilo getSilo(Integer siloId) { + public LabSilo getSilo(@Nonnull Integer siloId) { Criteria criteria = getSession().createCriteria(LabSilo.class); criteria.add(Restrictions.eq("id", String.valueOf(siloId))); return criteria.list() == null ? null : (LabSilo) criteria.list().get(0); } @Override - public void saveOrUpdate(LabSilo silo) { + public void saveOrUpdate(@Nonnull LabSilo silo) { getSession().saveOrUpdate(silo); + getSession().flush(); } @Override - public void merge(LabSilo silo) { + public void merge(@Nonnull LabSilo silo) { getSession().merge(silo); + getSession().flush(); } @Override - public void deleteSilo(LabSilo silo) { + public void deleteSilo(@Nonnull LabSilo silo) { getSession().delete(silo); + getSession().flush(); } @Override public void deleteAll() { if (getSession().createQuery("delete from Silo").executeUpdate() > 0) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "All silo entries are cleaned up"); + getSession().flush(); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/SubmissionDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/SubmissionDAOImpl.java index 7edab42..73e6e42 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/SubmissionDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/SubmissionDAOImpl.java @@ -17,6 +17,8 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.SubmissionDAO; import org.akraino.validation.ui.entity.Submission; import org.hibernate.Criteria; @@ -46,36 +48,41 @@ public class SubmissionDAOImpl implements SubmissionDAO { } @Override - public Submission getSubmission(Integer submissionId) { + public Submission getSubmission(@Nonnull Integer submissionId) { Criteria criteria = getSession().createCriteria(Submission.class); criteria.add(Restrictions.eq("id", submissionId)); return criteria.list() == null || criteria.list().size() < 1 ? null : (Submission) criteria.list().get(0); } @Override - public void saveOrUpdate(Submission submission) { + public void saveOrUpdate(@Nonnull Submission submission) { getSession().saveOrUpdate(submission); + getSession().flush(); } @Override - public void merge(Submission submission) { + public void merge(@Nonnull Submission submission) { getSession().merge(submission); + getSession().flush(); } @Override - public void deleteSubmission(Submission submission) { + public void deleteSubmission(@Nonnull Submission submission) { getSession().delete(submission); + getSession().flush(); } @Override - public void deleteSubmission(Integer submissionId) { + public void deleteSubmission(@Nonnull Integer submissionId) { getSession().delete(this.getSubmission(submissionId)); + getSession().flush(); } @Override public void deleteAll() { if (getSession().createQuery("delete from Submission").executeUpdate() > 0) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "All submission entries are cleaned up"); + getSession().flush(); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/TimeslotDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/TimeslotDAOImpl.java index a6cd925..f155944 100644 --- a/ui/src/main/java/org/akraino/validation/ui/daoimpl/TimeslotDAOImpl.java +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/TimeslotDAOImpl.java @@ -17,6 +17,8 @@ package org.akraino.validation.ui.daoimpl; import java.util.List; +import javax.annotation.Nonnull; + import org.akraino.validation.ui.dao.TimeslotDAO; import org.akraino.validation.ui.entity.Timeslot; import org.hibernate.Criteria; @@ -46,31 +48,35 @@ public class TimeslotDAOImpl implements TimeslotDAO { } @Override - public Timeslot getTimeslot(Integer timeslotId) { + public Timeslot getTimeslot(@Nonnull Integer timeslotId) { Criteria criteria = getSession().createCriteria(Timeslot.class); criteria.add(Restrictions.eq("id", String.valueOf(timeslotId))); return criteria.list() == null ? null : (Timeslot) criteria.list().get(0); } @Override - public void saveOrUpdate(Timeslot timeslot) { + public void saveOrUpdate(@Nonnull Timeslot timeslot) { getSession().saveOrUpdate(timeslot); + getSession().flush(); } @Override - public void merge(Timeslot timeslot) { + public void merge(@Nonnull Timeslot timeslot) { getSession().merge(timeslot); + getSession().flush(); } @Override - public void deleteTimeslot(Timeslot timeslot) { + public void deleteTimeslot(@Nonnull Timeslot timeslot) { getSession().delete(timeslot); + getSession().flush(); } @Override public void deleteAll() { if (getSession().createQuery("delete from Timeslot").executeUpdate() > 0) { LOGGER.info(EELFLoggerDelegate.applicationLogger, "All timeslot entries are cleaned up"); + getSession().flush(); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/ValidationTestResultDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/ValidationTestResultDAOImpl.java new file mode 100644 index 0000000..ab5e180 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/ValidationTestResultDAOImpl.java @@ -0,0 +1,144 @@ +/* + * 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.daoimpl; + +import java.util.List; + +import javax.annotation.Nonnull; + +import org.akraino.validation.ui.dao.ValidationTestResultDAO; +import org.akraino.validation.ui.entity.LabInfo; +import org.akraino.validation.ui.entity.Submission; +import org.akraino.validation.ui.entity.ValidationDbTestResult; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class ValidationTestResultDAOImpl implements ValidationTestResultDAO { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ValidationTestResultDAOImpl.class); + + @Autowired + private SessionFactory sessionFactory; + + protected Session getSession() { + return sessionFactory.getCurrentSession(); + } + + @Override + public List getValidationTestResults() { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + return criteria.list(); + } + + @Override + public ValidationDbTestResult getValidationTestResult(@Nonnull Integer resultId) { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + criteria.add(Restrictions.eq("id", String.valueOf(resultId))); + return criteria.list() == null ? null : (ValidationDbTestResult) criteria.list().get(0); + } + + @Override + public List getValidationTestResults(String blueprintName, String version, LabInfo labInfo, + Boolean allLayers, Boolean optional, Boolean outcome) { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + if (blueprintName != null) { + criteria.add(Restrictions.eq("blueprintName", String.valueOf(blueprintName))); + } + if (version != null) { + criteria.add(Restrictions.eq("version", String.valueOf(version))); + } + if (labInfo != null) { + criteria.add(Restrictions.eq("lab", labInfo)); + } + if (allLayers != null) { + criteria.add(Restrictions.eq("allLayers", allLayers)); + } + if (optional != null) { + criteria.add(Restrictions.eq("optional", optional)); + } + if (outcome != null) { + criteria.add(Restrictions.eq("result", outcome)); + } + return criteria.list() == null || criteria.list().size() == 0 ? null + : (List) criteria.list(); + } + + @Override + public ValidationDbTestResult getValidationTestResult(LabInfo labInfo, String timestamp) { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + if (labInfo != null) { + criteria.add(Restrictions.eq("lab", labInfo)); + } + if (timestamp != null) { + criteria.add(Restrictions.eq("timestamp", timestamp)); + } + return criteria.list() == null || criteria.list().size() == 0 ? null + : (ValidationDbTestResult) criteria.list().get(0); + } + + @Override + public ValidationDbTestResult getValidationTestResult(@Nonnull Submission submission) { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + criteria.add(Restrictions.eq("submission", submission)); + return criteria.list() == null || criteria.list().size() == 0 ? null + : (ValidationDbTestResult) criteria.list().get(0); + } + + @Override + public void saveOrUpdate(@Nonnull ValidationDbTestResult vResult) { + getSession().saveOrUpdate(vResult); + getSession().flush(); + } + + @Override + public void merge(@Nonnull ValidationDbTestResult vResult) { + getSession().merge(vResult); + getSession().flush(); + } + + @Override + public void deleteValidationTestResult(@Nonnull ValidationDbTestResult vResult) { + getSession().delete(vResult); + getSession().flush(); + } + + @Override + public void deleteValidationTestResult(@Nonnull LabInfo labInfo, @Nonnull String timestamp) { + Criteria criteria = getSession().createCriteria(ValidationDbTestResult.class); + criteria.add(Restrictions.eq("lab", labInfo)); + criteria.add(Restrictions.eq("timestamp", timestamp)); + if (criteria.list() == null || criteria.list().size() == 0) { + return; + } + getSession().delete(criteria.list().get(0)); + getSession().flush(); + } + + @Override + public void deleteAll() { + if (getSession().createQuery("delete from ValidationTestResult").executeUpdate() > 0) { + LOGGER.info(EELFLoggerDelegate.applicationLogger, "All validation test results are cleaned up"); + getSession().flush(); + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/daoimpl/WRobotTestResultDAOImpl.java b/ui/src/main/java/org/akraino/validation/ui/daoimpl/WRobotTestResultDAOImpl.java new file mode 100644 index 0000000..6c7a4c1 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/daoimpl/WRobotTestResultDAOImpl.java @@ -0,0 +1,102 @@ +/* + * 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.daoimpl; + +import java.util.List; + +import javax.annotation.Nonnull; + +import org.akraino.validation.ui.dao.WRobotTestResultDAO; +import org.akraino.validation.ui.entity.ValidationDbTestResult; +import org.akraino.validation.ui.entity.WRobotDbTestResult; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class WRobotTestResultDAOImpl implements WRobotTestResultDAO { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(WRobotTestResultDAOImpl.class); + + @Autowired + private SessionFactory sessionFactory; + + protected Session getSession() { + return sessionFactory.getCurrentSession(); + } + + @Override + public List getWRobotTestResults() { + Criteria criteria = getSession().createCriteria(WRobotDbTestResult.class); + return criteria.list(); + } + + @Override + public WRobotDbTestResult getWRobotTestResult(@Nonnull Integer wRobotResultId) { + Criteria criteria = getSession().createCriteria(WRobotDbTestResult.class); + criteria.add(Restrictions.eq("id", wRobotResultId)); + return criteria.list() == null || criteria.list().size() < 1 ? null + : (WRobotDbTestResult) criteria.list().get(0); + } + + @Override + public List getWRobotTestResult(@Nonnull ValidationDbTestResult vResult) { + Criteria criteria = getSession().createCriteria(WRobotDbTestResult.class); + criteria.add(Restrictions.eq("vResult", vResult)); + return criteria.list() == null || criteria.list().size() == 0 ? null + : (List) criteria.list(); + } + + @Override + public WRobotDbTestResult getWRobotTestResult(@Nonnull String layer, @Nonnull ValidationDbTestResult vResult) { + Criteria criteria = getSession().createCriteria(WRobotDbTestResult.class); + criteria.add(Restrictions.eq("layer", layer)); + criteria.add(Restrictions.eq("vResult", vResult)); + return criteria.list() == null || criteria.list().size() < 1 ? null + : (WRobotDbTestResult) criteria.list().get(0); + } + + @Override + public void saveOrUpdate(@Nonnull WRobotDbTestResult wResult) { + getSession().saveOrUpdate(wResult); + getSession().flush(); + } + + @Override + public void merge(@Nonnull WRobotDbTestResult wResult) { + getSession().merge(wResult); + getSession().flush(); + } + + @Override + public void deleteWRobotTestResult(@Nonnull Integer wRobotResultId) { + getSession().delete(this.getWRobotTestResult(wRobotResultId)); + getSession().flush(); + } + + @Override + public void deleteAll() { + if (getSession().createQuery("delete from WRobotTestResult").executeUpdate() > 0) { + LOGGER.info(EELFLoggerDelegate.applicationLogger, "All wrapper robot test results are cleaned up"); + getSession().flush(); + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/data/BlueprintLayer.java b/ui/src/main/java/org/akraino/validation/ui/data/BlueprintLayer.java index 9c57c04..6a67943 100644 --- a/ui/src/main/java/org/akraino/validation/ui/data/BlueprintLayer.java +++ b/ui/src/main/java/org/akraino/validation/ui/data/BlueprintLayer.java @@ -16,5 +16,5 @@ package org.akraino.validation.ui.data; public enum BlueprintLayer { - Hardware, Os, K8s, Kubeless, OpenStack, VNF, Application, All + hardware, os, k8s, kubeless, openstack, vnf, application, networking } diff --git a/ui/src/main/java/org/akraino/validation/ui/data/JnksJobNotify.java b/ui/src/main/java/org/akraino/validation/ui/data/JnksJobNotify.java index f72a307..ec86bda 100644 --- a/ui/src/main/java/org/akraino/validation/ui/data/JnksJobNotify.java +++ b/ui/src/main/java/org/akraino/validation/ui/data/JnksJobNotify.java @@ -32,6 +32,9 @@ public class JnksJobNotify { @JsonProperty("submissionId") private Integer submissionId; + @JsonProperty("timestamp") + private String timestamp; + public JnksJobNotify() { } @@ -60,4 +63,12 @@ public class JnksJobNotify { this.submissionId = submissionId; } + public String getTimestamp() { + return this.timestamp; + } + + public void setTimeStamp(String timestamp) { + this.timestamp = timestamp; + } + } diff --git a/ui/src/main/java/org/akraino/validation/ui/data/Lab.java b/ui/src/main/java/org/akraino/validation/ui/data/Lab.java index ae84d8e..c25d240 100644 --- a/ui/src/main/java/org/akraino/validation/ui/data/Lab.java +++ b/ui/src/main/java/org/akraino/validation/ui/data/Lab.java @@ -16,5 +16,5 @@ package org.akraino.validation.ui.data; public enum Lab { - ATT, Ericsson, Community, Arm + att, ericsson, community, arm } diff --git a/ui/src/main/java/org/akraino/validation/ui/data/SubmissionData.java b/ui/src/main/java/org/akraino/validation/ui/data/SubmissionData.java new file mode 100644 index 0000000..d5b8223 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/data/SubmissionData.java @@ -0,0 +1,66 @@ +/* + * 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.data; + +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.entity.Timeslot; + +public class SubmissionData { + + private int submissionId; + + private SubmissionStatus status; + + private Timeslot timeslot; + + private ValidationNexusTestResult validationNexusTestResult; + + public SubmissionData() { + + } + + public int getSubmissionId() { + return this.submissionId; + } + + public void setSubmissionId(int submissionId) { + this.submissionId = submissionId; + } + + public SubmissionStatus getStatus() { + return this.status; + } + + public void setStatus(SubmissionStatus status) { + this.status = status; + } + + public Timeslot getTimeslot() { + return this.timeslot; + } + + public void setTimeslot(Timeslot timeslot) { + this.timeslot = timeslot; + } + + public ValidationNexusTestResult getValidationNexusTestResult() { + return this.validationNexusTestResult; + } + + public void setValidationNexusTestResult(ValidationNexusTestResult validationNexusTestResult) { + this.validationNexusTestResult = validationNexusTestResult; + } +} diff --git a/ui/src/main/java/org/akraino/validation/ui/entity/LabInfo.java b/ui/src/main/java/org/akraino/validation/ui/entity/LabInfo.java index f046ce4..0d4801a 100644 --- a/ui/src/main/java/org/akraino/validation/ui/entity/LabInfo.java +++ b/ui/src/main/java/org/akraino/validation/ui/entity/LabInfo.java @@ -24,6 +24,8 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import org.akraino.validation.ui.data.Lab; + @Entity @Table(name = "lab") public class LabInfo implements Serializable { @@ -39,7 +41,7 @@ public class LabInfo implements Serializable { private int labId; @Column(name = "lab") - private org.akraino.validation.ui.data.Lab lab; + private Lab lab; public int getLabId() { return labId; @@ -49,11 +51,11 @@ public class LabInfo implements Serializable { this.labId = labId; } - public org.akraino.validation.ui.data.Lab getLab() { + public Lab getLab() { return lab; } - public void setLab(org.akraino.validation.ui.data.Lab lab) { + public void setLab(Lab lab) { this.lab = lab; } } diff --git a/ui/src/main/java/org/akraino/validation/ui/entity/Submission.java b/ui/src/main/java/org/akraino/validation/ui/entity/Submission.java index 797343f..bdbe535 100644 --- a/ui/src/main/java/org/akraino/validation/ui/entity/Submission.java +++ b/ui/src/main/java/org/akraino/validation/ui/entity/Submission.java @@ -45,16 +45,6 @@ public class Submission implements Serializable { @Column(name = "status") private SubmissionStatus status; - @Column(name = "jenkins_queue_job_item_url") - private String jnksJobUrl; - - @Column(name = "nexus_result_url") - private String nexusResultUrl; - - @ManyToOne - @JoinColumn(name = "blueprint_instance_for_validation_id") - private BlueprintInstanceForValidation blueprintInst; - @ManyToOne @JoinColumn(name = "timeslot_id") private Timeslot timeslot; @@ -75,31 +65,6 @@ public class Submission implements Serializable { this.status = submissionStatus; } - public String getJenkinsQueueJobItemUrl() { - return this.jnksJobUrl; - } - - public void setJnksQueueJobItemUrl(String url) { - this.jnksJobUrl = url; - } - - public String getNexusResultUrl() { - return this.nexusResultUrl; - } - - public void setNexusResultUrl(String nexusResultUrl) { - this.nexusResultUrl = nexusResultUrl; - } - - public void setBlueprintInstanceForValidation(BlueprintInstanceForValidation blueprintInst) { - this.blueprintInst = blueprintInst; - } - - public BlueprintInstanceForValidation getBlueprintInstanceForValidation() { - return this.blueprintInst; - } - - public void setTimeslot(Timeslot timeslot) { this.timeslot = timeslot; } @@ -108,5 +73,4 @@ public class Submission implements Serializable { return this.timeslot; } - } diff --git a/ui/src/main/java/org/akraino/validation/ui/entity/ValidationDbTestResult.java b/ui/src/main/java/org/akraino/validation/ui/entity/ValidationDbTestResult.java new file mode 100644 index 0000000..6a447eb --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/entity/ValidationDbTestResult.java @@ -0,0 +1,153 @@ +/* + * 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.entity; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "validation_test_result") +public class ValidationDbTestResult implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private int resultId; + + @Column(name = "blueprint_name") + private String blueprintName; + + @Column(name = "version") + private String version; + + @ManyToOne + @JoinColumn(name = "lab_id") + private LabInfo lab; + + @Column(name = "timestamp") + private String timestamp; + + @Column(name = "all_layers") + private Boolean allLayers; + + @Column(name = "optional") + private Boolean optional; + + @Column(name = "result") + private Boolean result; + + @Column(name = "date_of_storage") + private String dateStorage; + + @OneToOne + @JoinColumn(name = "submission_id") + private Submission submission; + + public int getResultId() { + return resultId; + } + + public void setResultId(int resultId) { + this.resultId = resultId; + } + + public String getBlueprintName() { + return blueprintName; + } + + public void setBlueprintName(String blueprintName) { + this.blueprintName = blueprintName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Boolean getAllLayers() { + return allLayers; + } + + public void setAllLayers(Boolean allLayers) { + this.allLayers = allLayers; + } + + public Boolean getOptional() { + return optional; + } + + public void setOptional(Boolean optional) { + this.optional = optional; + } + + public LabInfo getLab() { + return lab; + } + + public void setLab(LabInfo lab) { + this.lab = lab; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public Boolean getResult() { + return result; + } + + public void setResult(Boolean result) { + this.result = result; + } + + public String getDateStorage() { + return dateStorage; + } + + public void setDateStorage(String dateStorage) { + this.dateStorage = dateStorage; + } + + public Submission getSubmission() { + return this.submission; + } + + public void setSubmission(Submission submission) { + this.submission = submission; + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/entity/WRobotDbTestResult.java b/ui/src/main/java/org/akraino/validation/ui/entity/WRobotDbTestResult.java new file mode 100644 index 0000000..282a83e --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/entity/WRobotDbTestResult.java @@ -0,0 +1,85 @@ +/* + * 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.entity; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "w_robot_test_result") +public class WRobotDbTestResult implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private int wRobotResultId; + + @Column(name = "layer") + private String layer; + + @ManyToOne + @JoinColumn(name = "validation_test_result_id") + private ValidationDbTestResult vResult; + + @Column(name = "robot_test_results") + private String rResults; + + public int getWRobotResultId() { + return wRobotResultId; + } + + public void setWRobotResultId(int wRobotResultId) { + this.wRobotResultId = wRobotResultId; + } + + public String getLayer() { + return layer; + } + + public void setLayer(String layer) { + this.layer = layer; + } + + public ValidationDbTestResult getValidationTestResult() { + return vResult; + } + + public void setValidationTestResult(ValidationDbTestResult vResult) { + this.vResult = vResult; + } + + public String getRobotTestResults() { + return rResults; + } + + public void setRobotTestResults(String rResults) { + this.rResults = rResults; + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/BlueprintInstanceForValidationService.java b/ui/src/main/java/org/akraino/validation/ui/service/BlueprintInstanceForValidationService.java index d786d09..707d686 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/BlueprintInstanceForValidationService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/BlueprintInstanceForValidationService.java @@ -31,15 +31,11 @@ public class BlueprintInstanceForValidationService { private BlueprintInstanceForValidationDAO dao; public void saveBlueprintInstance(BlueprintInstanceForValidation blueprintIns) { - dao.saveOrUpdate(blueprintIns); - } public List getBlueprintInstancesForValidation() { - return dao.getBlueprintInstancesForValidation(); - } public void deleteAll() { diff --git a/ui/src/main/java/org/akraino/validation/ui/service/BlueprintService.java b/ui/src/main/java/org/akraino/validation/ui/service/BlueprintService.java index ddc0219..37e2c0b 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/BlueprintService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/BlueprintService.java @@ -31,15 +31,11 @@ public class BlueprintService { private BlueprintDAO blueprintDAO; public void saveBlueprint(Blueprint blueprint) { - blueprintDAO.saveOrUpdate(blueprint); - } public List getBlueprints() { - return blueprintDAO.getBlueprints(); - } public void deleteAll() { diff --git a/ui/src/main/java/org/akraino/validation/ui/service/DbResultAdapter.java b/ui/src/main/java/org/akraino/validation/ui/service/DbResultAdapter.java new file mode 100644 index 0000000..7e8687f --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/service/DbResultAdapter.java @@ -0,0 +1,510 @@ +package org.akraino.validation.ui.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import javax.annotation.Nonnull; + +import org.akraino.validation.ui.client.nexus.resources.RobotTestResult; +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.client.nexus.resources.WRobotNexusTestResult; +import org.akraino.validation.ui.dao.ValidationTestResultDAO; +import org.akraino.validation.ui.dao.WRobotTestResultDAO; +import org.akraino.validation.ui.data.BlueprintLayer; +import org.akraino.validation.ui.data.JnksJobNotify; +import org.akraino.validation.ui.data.Lab; +import org.akraino.validation.ui.data.SubmissionData; +import org.akraino.validation.ui.entity.LabInfo; +import org.akraino.validation.ui.entity.LabSilo; +import org.akraino.validation.ui.entity.Submission; +import org.akraino.validation.ui.entity.ValidationDbTestResult; +import org.akraino.validation.ui.entity.WRobotDbTestResult; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Service +@Transactional +public class DbResultAdapter { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(DbResultAdapter.class); + private static final Object LOCK = new Object(); + + @Autowired + LabService labService; + + @Autowired + private ValidationTestResultDAO vTestResultDAO; + + @Autowired + private WRobotTestResultDAO wRobotDAO; + + @Autowired + private SiloService siloService; + + @Autowired + DbSubmissionAdapter subService; + + public void associateSubmissionWithValidationResult(SubmissionData submissionData) + throws JsonParseException, JsonMappingException, IOException { + synchronized (LOCK) { + ValidationDbTestResult vDbTestResult = this + .convertValidationNexusToDb(submissionData.getValidationNexusTestResult()); + Submission submission = new Submission(); + submission.setSubmissionId(submissionData.getSubmissionId()); + vDbTestResult.setSubmission(submission); + vTestResultDAO.saveOrUpdate(vDbTestResult); + List vRobotDbResults = this.convertWRobotNexusResultsToDb( + submissionData.getValidationNexusTestResult().getwRobotNexusTestResults()); + if (vRobotDbResults != null) { + for (WRobotDbTestResult vRobotDbResult : vRobotDbResults) { + vRobotDbResult.setValidationTestResult(vDbTestResult); + wRobotDAO.saveOrUpdate(vRobotDbResult); + } + } + } + } + + public void storeResultInDb(List vNexusResults) { + synchronized (LOCK) { + if (vNexusResults == null || vNexusResults.size() < 1) { + return; + } + for (ValidationNexusTestResult vNexusResult : vNexusResults) { + if (!checkValidityOfValidationNexusTestResult(vNexusResult)) { + continue; + } + LabInfo labInfo = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(vNexusResult.getSilo())) { + labInfo = silo.getLab(); + } + } + ValidationDbTestResult vDbResult = vTestResultDAO.getValidationTestResult(labInfo, + vNexusResult.getTimestamp()); + if (vDbResult == null) { + vDbResult = new ValidationDbTestResult(); + vDbResult.setLab(labInfo); + vDbResult.setTimestamp(vNexusResult.getTimestamp()); + vDbResult.setBlueprintName(vNexusResult.getBlueprintName()); + vDbResult.setVersion(vNexusResult.getVersion()); + vDbResult.setAllLayers(vNexusResult.getAllLayers()); + vDbResult.setOptional(vNexusResult.getOptional()); + } + vDbResult.setResult(vNexusResult.getResult()); + vDbResult.setDateStorage(vNexusResult.getDateOfStorage()); + LOGGER.debug(EELFLoggerDelegate.debugLogger, + "Storing validation test result with keys: blueprint name: " + vNexusResult.getBlueprintName() + + ", version: " + vNexusResult.getVersion() + ", lab: " + vNexusResult.getSilo() + + ", timestamp: " + vNexusResult.getTimestamp()); + vTestResultDAO.saveOrUpdate(vDbResult); + List wRobotDbResults = wRobotDAO + .getWRobotTestResult(vDbResult); + if (wRobotDbResults == null) { + // Store the new wrapper robot rest results in db + for (WRobotNexusTestResult wNexusResult : vNexusResult.getwRobotNexusTestResults()) { + WRobotDbTestResult wRobotDbResult = new WRobotDbTestResult(); + wRobotDbResult.setLayer(wNexusResult.getBlueprintLayer().name()); + wRobotDbResult.setValidationTestResult(vDbResult); + ObjectMapper mapper = new ObjectMapper(); + try { + wRobotDbResult + .setRobotTestResults(mapper.writeValueAsString(wNexusResult.getRobotTestResults())); + } catch (JsonProcessingException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error while converting POJO to string. " + UserUtils.getStackTrace(e)); + continue; + } + wRobotDAO.saveOrUpdate(wRobotDbResult); + } + } else if (vDbResult.getSubmission() != null) { + // update validation result related to submission + for (WRobotNexusTestResult wNexusResult : vNexusResult.getwRobotNexusTestResults()) { + WRobotDbTestResult wRobotDbResult = wRobotDAO + .getWRobotTestResult(wNexusResult.getBlueprintLayer().name(), vDbResult); + ObjectMapper mapper = new ObjectMapper(); + try { + wRobotDbResult + .setRobotTestResults(mapper.writeValueAsString(wNexusResult.getRobotTestResults())); + } catch (JsonProcessingException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error while converting POJO to string. " + UserUtils.getStackTrace(e)); + continue; + } + wRobotDAO.saveOrUpdate(wRobotDbResult); + } + } + } + } + } + + public void updateTimestamp(JnksJobNotify jnksJobNotify) { + synchronized (LOCK) { + if (!checkValidityOfJenkinsNotification(jnksJobNotify)) { + return; + } + ValidationDbTestResult vDbSubmission = vTestResultDAO + .getValidationTestResult(subService.getSubmission(String.valueOf(jnksJobNotify.getSubmissionId()))); + ValidationDbTestResult vDbTimestamp = vTestResultDAO.getValidationTestResult(vDbSubmission.getLab(), + jnksJobNotify.getTimestamp()); + if (vDbTimestamp == null) { + vDbSubmission.setTimestamp(jnksJobNotify.getTimestamp()); + vTestResultDAO.saveOrUpdate(vDbSubmission); + return; + } + // Delete the wrobot results associated with submission validation result + List wRobotResults = wRobotDAO.getWRobotTestResult(vDbSubmission); + if (wRobotResults != null && wRobotResults.size() > 0) { + for (WRobotDbTestResult wRobotResult : wRobotResults) { + wRobotDAO.deleteWRobotTestResult(wRobotResult.getWRobotResultId()); + } + } + // Change the timestamp wrobot results to point to submission validation result + wRobotResults = wRobotDAO.getWRobotTestResult(vDbTimestamp); + if (wRobotResults != null && wRobotResults.size() > 0) { + for (WRobotDbTestResult wRobotResult : wRobotResults) { + wRobotResult.setValidationTestResult(vDbSubmission); + wRobotDAO.saveOrUpdate(wRobotResult); + } + } + vTestResultDAO.deleteValidationTestResult(vDbTimestamp); + // Now vDbSubmission can be updated + vDbSubmission.setDateStorage(vDbTimestamp.getDateStorage()); + vDbSubmission.setResult(vDbTimestamp.getResult()); + vDbSubmission.setTimestamp(vDbTimestamp.getTimestamp()); + vTestResultDAO.saveOrUpdate(vDbSubmission); + } + } + + public List readResultFromDb(String blueprintName, String version, Lab lab, + List layers, Boolean allLayers, Boolean optional, Boolean outcome) + throws JsonParseException, JsonMappingException, IOException { + synchronized (LOCK) { + LabInfo actualLabInfo = labService.getLab(lab); + List vDbResults = vTestResultDAO.getValidationTestResults(blueprintName, version, + actualLabInfo, allLayers, optional, outcome); + if (vDbResults == null || vDbResults.size() < 1) { + return null; + } + List vNexusResults = new ArrayList(); + for (ValidationDbTestResult vDbResult : vDbResults) { + if (layers != null && layers.size() > 0) { + List storedLayers = new ArrayList(); + List wDbResults = wRobotDAO.getWRobotTestResult(vDbResult); + if (wDbResults == null || wDbResults.size() < 1) { + continue; + } + for (WRobotDbTestResult wRobot : wDbResults) { + storedLayers.add(BlueprintLayer.valueOf(wRobot.getLayer())); + } + if (!new HashSet<>(storedLayers).equals(new HashSet<>(layers))) { + continue; + } + } + vNexusResults.add(convertValidationDbToNexus(vDbResult)); + } + return vNexusResults; + } + } + + public ValidationNexusTestResult readResultFromDb(@Nonnull Lab lab, @Nonnull String timestamp) + throws JsonParseException, JsonMappingException, IOException { + synchronized (LOCK) { + LabInfo actualLabInfo = labService.getLab(lab); + ValidationDbTestResult vDbResult = vTestResultDAO.getValidationTestResult(actualLabInfo, timestamp); + if (vDbResult == null) { + return null; + } + return convertValidationDbToNexus(vDbResult); + } + } + + public ValidationNexusTestResult readResultFromDb(@Nonnull String submissionId) + throws JsonParseException, JsonMappingException, IOException { + synchronized (LOCK) { + ValidationDbTestResult vDbResult = vTestResultDAO + .getValidationTestResult(subService.getSubmission(submissionId)); + if (vDbResult == null) { + return null; + } + return convertValidationDbToNexus(vDbResult); + } + } + + public void deleteUnreferencedEntries(List vNexusResults) { + synchronized (LOCK) { + if (vNexusResults == null || vNexusResults.size() < 1) { + return; + } + LabInfo labInfo = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(vNexusResults.get(0).getSilo())) { + labInfo = silo.getLab(); + } + } + if (labInfo == null) { + return; + } + List vDbResults = vTestResultDAO.getValidationTestResults( + vNexusResults.get(0).getBlueprintName(), vNexusResults.get(0).getVersion(), labInfo, null, null, + null); + if (vDbResults == null || vDbResults.size() < 1) { + return; + } + for (ValidationDbTestResult vDbResult : vDbResults) { + if (vDbResult.getSubmission() != null) { + continue; + } + boolean deletion = true; + String dbTimestamp = vDbResult.getTimestamp(); + LabInfo dbLabInfo = vDbResult.getLab(); + for (ValidationNexusTestResult vNexusResult : vNexusResults) { + LabInfo nexusLabInfo = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(vNexusResult.getSilo())) { + nexusLabInfo = silo.getLab(); + } + } + if (nexusLabInfo == null) { + continue; + } + if (vNexusResult.getTimestamp().equals(dbTimestamp) && nexusLabInfo.equals(dbLabInfo)) { + deletion = false; + break; + } + } + if (deletion) { + LOGGER.debug(EELFLoggerDelegate.debugLogger, + "Deleting unreferenced validation result with id: " + vDbResult.getResultId()); + // Delete old associated wrapper robot rest results from db + for (WRobotDbTestResult wRobotDbResult : wRobotDAO.getWRobotTestResult(vDbResult)) { + wRobotDAO.deleteWRobotTestResult(wRobotDbResult.getWRobotResultId()); + } + vTestResultDAO.deleteValidationTestResult(vDbResult); + } + } + + } + } + + public List getValidationTestResults() { + synchronized (LOCK) { + return vTestResultDAO.getValidationTestResults(); + } + } + + public ValidationDbTestResult getValidationTestResult(Integer resultId) { + synchronized (LOCK) { + return vTestResultDAO.getValidationTestResult(resultId); + } + } + + public List getValidationTestResults(String blueprintName, String version, LabInfo labInfo, + Boolean allLayers, Boolean optional, Boolean outcome) { + synchronized (LOCK) { + return vTestResultDAO.getValidationTestResults(blueprintName, version, labInfo, allLayers, optional, + outcome); + } + } + + public ValidationDbTestResult getValidationTestResult(LabInfo labInfo, String timestamp) { + synchronized (LOCK) { + return vTestResultDAO.getValidationTestResult(labInfo, timestamp); + } + } + + public ValidationDbTestResult getValidationTestResult(@Nonnull Submission submission) { + synchronized (LOCK) { + return vTestResultDAO.getValidationTestResult(submission); + } + } + + public List getWRobotTestResults() { + synchronized (LOCK) { + return wRobotDAO.getWRobotTestResults(); + } + } + + public WRobotDbTestResult getWRobotTestResult(Integer wRobotResultId) { + synchronized (LOCK) { + return wRobotDAO.getWRobotTestResult(wRobotResultId); + } + } + + public List getWRobotTestResult(ValidationDbTestResult vResult) { + synchronized (LOCK) { + return wRobotDAO.getWRobotTestResult(vResult); + } + } + + private ValidationNexusTestResult convertValidationDbToNexus(ValidationDbTestResult vDbResult) + throws JsonParseException, JsonMappingException, IOException { + ValidationNexusTestResult vNexusResult = new ValidationNexusTestResult(); + vNexusResult.setResultId(vDbResult.getResultId()); + vNexusResult.setBlueprintName(vDbResult.getBlueprintName()); + vNexusResult.setVersion(vDbResult.getVersion()); + vNexusResult.setAllLayers(vDbResult.getAllLayers()); + vNexusResult.setDateOfStorage(vDbResult.getDateStorage()); + vNexusResult.setOptional(vDbResult.getOptional()); + vNexusResult.setResult(vDbResult.getResult()); + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(vDbResult.getLab().getLab())) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Lab does not exist: " + vDbResult.getLab().toString()); + } + vNexusResult.setSilo(siloText); + vNexusResult.setTimestamp(vDbResult.getTimestamp()); + if (vDbResult.getSubmission() != null) { + vNexusResult.setSubmissionId(String.valueOf(vDbResult.getSubmission().getSubmissionId())); + } + List wNexusResults = new ArrayList(); + List wDbResults = wRobotDAO.getWRobotTestResult(vDbResult); + if (wDbResults != null && wDbResults.size() > 0) { + for (WRobotDbTestResult wRobot : wDbResults) { + WRobotNexusTestResult wNexusResult = new WRobotNexusTestResult(); + wNexusResult.setBlueprintLayer(BlueprintLayer.valueOf(wRobot.getLayer())); + if (wRobot.getRobotTestResults() != null) { + ObjectMapper mapper = new ObjectMapper(); + wNexusResult.setRobotTestResults( + mapper.readValue(wRobot.getRobotTestResults(), new TypeReference>() { + })); + } + wNexusResults.add(wNexusResult); + } + vNexusResult.setwRobotNexusTestResults(wNexusResults); + } + return vNexusResult; + } + + private ValidationDbTestResult convertValidationNexusToDb(ValidationNexusTestResult vNexusResult) + throws JsonParseException, JsonMappingException, IOException { + LabInfo labInfo = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(vNexusResult.getSilo())) { + labInfo = silo.getLab(); + } + } + if (labInfo == null) { + return null; + } + ValidationDbTestResult vDbResult = new ValidationDbTestResult(); + vDbResult.setBlueprintName(vNexusResult.getBlueprintName()); + vDbResult.setVersion(vNexusResult.getVersion()); + vDbResult.setLab(labInfo); + vDbResult.setOptional(vNexusResult.getOptional()); + vDbResult.setAllLayers(vNexusResult.getAllLayers()); + vDbResult.setDateStorage(vNexusResult.getDateOfStorage()); + vDbResult.setResult(vNexusResult.getResult()); + vDbResult.setTimestamp(vNexusResult.getTimestamp()); + return vDbResult; + } + + private List convertWRobotNexusResultsToDb(List wRobotNexusResults) { + if (wRobotNexusResults == null || wRobotNexusResults.size() < 1) { + return null; + } + List wDbResults = new ArrayList(); + for (WRobotNexusTestResult wRobotNexusResult : wRobotNexusResults) { + WRobotDbTestResult wDbResult = new WRobotDbTestResult(); + if (wRobotNexusResult.getBlueprintLayer() != null) { + wDbResult.setLayer(wRobotNexusResult.getBlueprintLayer().toString()); + } + ObjectMapper mapper = new ObjectMapper(); + if (wRobotNexusResult.getRobotTestResults() != null && wRobotNexusResult.getRobotTestResults().size() > 0) { + try { + wDbResult.setRobotTestResults(mapper.writeValueAsString(wRobotNexusResult.getRobotTestResults())); + } catch (JsonProcessingException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error while converting POJO to string. " + UserUtils.getStackTrace(e)); + continue; + } + } + wDbResults.add(wDbResult); + } + return wDbResults; + } + + private boolean checkValidityOfValidationNexusTestResult(ValidationNexusTestResult vNexusResult) { + LabInfo labInfo = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(vNexusResult.getSilo())) { + labInfo = silo.getLab(); + } + } + if (labInfo == null) { + LOGGER.error(EELFLoggerDelegate.errorLogger, "No lab Info found for silo. " + vNexusResult.getSilo()); + return false; + } + ValidationDbTestResult vDbResult = vTestResultDAO.getValidationTestResult(labInfo, vNexusResult.getTimestamp()); + if (vDbResult != null) { + // Be elastic for allLayers and optional + if (!vDbResult.getBlueprintName().equals(vNexusResult.getBlueprintName()) + || !vDbResult.getVersion().equals(vNexusResult.getVersion()) || !vDbResult.getLab().equals(labInfo) + || !vDbResult.getTimestamp().equals(vNexusResult.getTimestamp())) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Nexus has different data for blueprint : " + vDbResult.getBlueprintName() + ", version: " + + vDbResult.getVersion() + " and lab: " + vDbResult.getLab().getLab().name()); + return false; + } + } + List wRobotDbResults = wRobotDAO + .getWRobotTestResult(vDbResult); + if (wRobotDbResults != null) { + if (vDbResult.getSubmission() != null) { + for (WRobotNexusTestResult wNexusResult : vNexusResult.getwRobotNexusTestResults()) { + WRobotDbTestResult wRobotDbResult = wRobotDAO + .getWRobotTestResult(wNexusResult.getBlueprintLayer().name(), vDbResult); + if (wRobotDbResult == null) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Nexus has different layer results for submission id: " + + vDbResult.getSubmission().getSubmissionId()); + return false; + } + } + } + } + return true; + } + + private boolean checkValidityOfJenkinsNotification(JnksJobNotify jnksJobNotify) { + ValidationDbTestResult vDbSubmission = vTestResultDAO + .getValidationTestResult(subService.getSubmission(String.valueOf(jnksJobNotify.getSubmissionId()))); + if (vDbSubmission == null) { + return false; + } + ValidationDbTestResult vDbTimestamp = vTestResultDAO.getValidationTestResult(vDbSubmission.getLab(), + jnksJobNotify.getTimestamp()); + if (vDbTimestamp == null) { + return true; + } + if (vDbTimestamp.equals(vDbSubmission) || (vDbTimestamp.getSubmission() != null + && !jnksJobNotify.getSubmissionId().equals(vDbTimestamp.getSubmission().getSubmissionId()))) { + LOGGER.error(EELFLoggerDelegate.errorLogger, "Received same timestamp: " + jnksJobNotify.getTimestamp() + + " from nexus for submission id: " + jnksJobNotify.getSubmissionId()); + return false; + } + // Be elastic for allLayers and optional + if (!vDbSubmission.getBlueprintName().equals(vDbTimestamp.getBlueprintName()) + || !vDbSubmission.getVersion().equals(vDbTimestamp.getVersion()) + || !vDbSubmission.getLab().equals(vDbTimestamp.getLab())) { + LOGGER.error(EELFLoggerDelegate.errorLogger, "No consistency exists in database records."); + return false; + } + return true; + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/DbSubmissionAdapter.java b/ui/src/main/java/org/akraino/validation/ui/service/DbSubmissionAdapter.java new file mode 100644 index 0000000..977e89d --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/service/DbSubmissionAdapter.java @@ -0,0 +1,218 @@ +/* + * 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.service; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; + +import org.akraino.validation.ui.client.jenkins.JenkinsExecutorClient; +import org.akraino.validation.ui.client.jenkins.resources.Parameter; +import org.akraino.validation.ui.client.jenkins.resources.Parameters; +import org.akraino.validation.ui.conf.ExecutorServiceInitializer; +import org.akraino.validation.ui.dao.SubmissionDAO; +import org.akraino.validation.ui.data.SubmissionData; +import org.akraino.validation.ui.data.SubmissionStatus; +import org.akraino.validation.ui.entity.LabSilo; +import org.akraino.validation.ui.entity.Submission; +import org.akraino.validation.ui.service.utils.PrioritySupplier; +import org.akraino.validation.ui.service.utils.SubmissionHelper; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +@Service +@Transactional +public class DbSubmissionAdapter { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(DbSubmissionAdapter.class); + + @Autowired + private SubmissionDAO submissionDAO; + + @Autowired + private SubmissionHelper submissionHelper; + + @Autowired + private JenkinsExecutorClient jenkinsService; + + @Autowired + private DbResultAdapter dbAdapter; + + @Autowired + SiloService siloService; + + public SubmissionData saveSubmission(SubmissionData submissionData) + throws JsonParseException, JsonMappingException, IOException { + Submission submission = new Submission(); + submission.setSubmissionStatus(SubmissionStatus.Submitted); + submission.setTimeslot(submissionData.getTimeslot()); + submissionDAO.saveOrUpdate(submission); + submissionData.setSubmissionId(submission.getSubmissionId()); + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(submissionData.getTimeslot().getLab().getLab())) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException( + "Lab does not exist: " + submissionData.getTimeslot().getLab().toString()); + } + submissionData.getValidationNexusTestResult().setSilo(siloText); + dbAdapter.associateSubmissionWithValidationResult(submissionData); + ApplicationContext context = new AnnotationConfigApplicationContext(ExecutorServiceInitializer.class); + ExecutorService service = (ExecutorService) context.getBean("executorService"); + JenkinsTriggerSubmissionJob task = new JenkinsTriggerSubmissionJob(submissionData); + CompletableFuture completableFuture = CompletableFuture + .supplyAsync(new PrioritySupplier<>(1, task::execute), service); + completableFuture.thenAcceptAsync(result -> this.callbackNotify(result)); + submissionData.setSubmissionId(submission.getSubmissionId()); + return submissionData; + } + + public List getSubmissions() { + return submissionDAO.getSubmissions(); + } + + public List getSubmissionDatas() throws JsonParseException, JsonMappingException, IOException { + List submissions = submissionDAO.getSubmissions(); + if (submissions == null || submissions.size() < 1) { + return null; + } + List datas = new ArrayList(); + for (Submission submission : submissions) { + SubmissionData submissionData = new SubmissionData(); + submissionData.setStatus(submission.getSubmissionStatus()); + submissionData.setSubmissionId(submission.getSubmissionId()); + submissionData.setTimeslot(submission.getTimeslot()); + submissionData.setValidationNexusTestResult( + dbAdapter.readResultFromDb(String.valueOf(submission.getSubmissionId()))); + datas.add(submissionData); + } + return datas; + } + + public SubmissionData getSubmissionData(String submissionId) + throws JsonParseException, JsonMappingException, IOException { + Submission submission = submissionDAO.getSubmission(Integer.valueOf(submissionId)); + if (submission == null) { + return null; + } + SubmissionData submissionData = new SubmissionData(); + submissionData.setStatus(submission.getSubmissionStatus()); + submissionData.setSubmissionId(submission.getSubmissionId()); + submissionData.setTimeslot(submission.getTimeslot()); + submissionData.setValidationNexusTestResult(dbAdapter.readResultFromDb(submissionId)); + return submissionData; + } + + public Submission getSubmission(String submissionId) { + return submissionDAO.getSubmission(Integer.valueOf(submissionId)); + } + + public void deleteSubmission(Integer submissionId) { + submissionDAO.deleteSubmission(submissionId); + } + + public void deleteAll() { + submissionDAO.deleteAll(); + } + + private void callbackNotify(SubmissionData submissionData) { + if (submissionData == null) { + return; + } + Submission submission = submissionHelper.getSubmission(submissionData.getSubmissionId()); + submission.setSubmissionStatus(SubmissionStatus.Running); + submissionHelper.saveSubmission(submission); + } + + private class JenkinsTriggerSubmissionJob { + + private SubmissionData submissionData; + + public JenkinsTriggerSubmissionJob(SubmissionData submissionData) { + this.submissionData = submissionData; + } + + public SubmissionData execute() { + try (final DatagramSocket socket = new DatagramSocket()) { + String jobName = System.getenv("JENKINS_JOB_NAME"); + List listOfParameters = new ArrayList(); + Parameters parameters = new Parameters(); + Parameter parameter = new Parameter(); + parameter.setName("SUBMISSION_ID"); + parameter.setValue(String.valueOf(submissionData.getSubmissionId())); + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("BLUEPRINT"); + parameter.setValue(submissionData.getValidationNexusTestResult().getBlueprintName()); + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("LAYER"); + if (submissionData.getValidationNexusTestResult().getAllLayers()) { + parameter.setValue("all"); + } else { + parameter.setValue(submissionData.getValidationNexusTestResult().getwRobotNexusTestResults().get(0) + .getBlueprintLayer().name().toLowerCase()); + } + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("VERSION"); + parameter.setValue(submissionData.getValidationNexusTestResult().getVersion()); + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("LAB"); + parameter.setValue(submissionData.getTimeslot().getLab().getLab().name()); + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("OPTIONAL"); + parameter.setValue( + String.valueOf(submissionData.getValidationNexusTestResult().getOptional().toString())); + listOfParameters.add(parameter); + parameter = new Parameter(); + parameter.setName("UI_IP"); + Random random = new Random(); + socket.connect(InetAddress.getByName(random.nextInt(256) + "." + random.nextInt(256) + "." + + random.nextInt(256) + "." + random.nextInt(256)), 10002); + String localIP = socket.getLocalAddress().getHostAddress(); + parameter.setValue(localIP); + listOfParameters.add(parameter); + parameters.setParameter(listOfParameters); + jenkinsService.postJobWithQueryParams(jobName, parameters).toString(); + return submissionData; + } catch (Exception e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when triggering Jenkins job. " + UserUtils.getStackTrace(e)); + return null; + } + } + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/IntegratedResultService.java b/ui/src/main/java/org/akraino/validation/ui/service/IntegratedResultService.java new file mode 100644 index 0000000..0015590 --- /dev/null +++ b/ui/src/main/java/org/akraino/validation/ui/service/IntegratedResultService.java @@ -0,0 +1,336 @@ +/* + * 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.service; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import javax.annotation.Nonnull; + +import org.akraino.validation.ui.client.nexus.NexusExecutorClient; +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.data.BlueprintLayer; +import org.akraino.validation.ui.data.Lab; +import org.akraino.validation.ui.data.SubmissionData; +import org.akraino.validation.ui.entity.LabInfo; +import org.akraino.validation.ui.entity.LabSilo; +import org.akraino.validation.ui.entity.ValidationDbTestResult; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.UniformInterfaceException; + +@Service +@Transactional +public class IntegratedResultService { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(IntegratedResultService.class); + + @Autowired + private DbSubmissionAdapter submissionService; + + @Autowired + private SiloService siloService; + + @Autowired + NexusExecutorClient nexusService; + + @Autowired + LabService labService; + + @Autowired + DbResultAdapter dbAdapter; + + public List getLabsFromNexus() + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, IllegalArgumentException, ParseException { + List labs = new ArrayList(); + for (String cLabSilo : nexusService.getResource(null)) { + for (LabSilo silo : siloService.getSilos()) { + if (silo.getSilo().equals(cLabSilo)) { + labs.add(silo.getLab().getLab()); + } + } + } + return labs; + } + + public List getBlueprintNamesOfLabFromNexus(@Nonnull Lab lab) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, IllegalArgumentException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Could not retrieve blueprint names of lab : " + lab.toString()); + } + List blueprintNames = new ArrayList(); + List cBlueprintNames = nexusService.getResource(siloText); + for (String cBlueprintName : cBlueprintNames) { + if (!cBlueprintName.equals("job")) { + blueprintNames.add(cBlueprintName); + } + } + return blueprintNames; + } + + public List getBlueprintVersionsFromNexus(@Nonnull String name, @Nonnull Lab lab) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, IllegalArgumentException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Could not retrieve silo of the lab : " + lab.toString()); + } + return nexusService.getResource(siloText, name); + } + + public List getBlueprintTimeStampsFromNexus(@Nonnull String name, @Nonnull String version, @Nonnull Lab lab) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Could not retrieve silo of the lab : " + lab.toString()); + } + return nexusService.getResource(siloText, name, version); + } + + public List getResultsFromNexus(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, int noTimestamps) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, IllegalArgumentException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Could not retrieve silo of the lab : " + lab.toString()); + } + return nexusService.getResults(name, version, siloText, noTimestamps); + } + + public ValidationNexusTestResult getResultFromNexus(@Nonnull String name, @Nonnull String version, @Nonnull Lab lab, + @Nonnull String timestamp) throws JsonParseException, JsonMappingException, IOException, + KeyManagementException, ClientHandlerException, UniformInterfaceException, NoSuchAlgorithmException, + NullPointerException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Could not retrieve silo of the lab : " + lab.toString()); + } + return nexusService.getResult(name, version, siloText, timestamp); + } + + public ValidationNexusTestResult getLastResultBasedOnOutcomeFromNexus(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, Boolean allLayers, Boolean optional, boolean outcome) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, NullPointerException, IOException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Lab does not exist: " + lab.toString()); + } + return nexusService.getLastResultBasedOnOutcome(name, version, siloText, allLayers, optional, outcome); + } + + public ValidationNexusTestResult getLastResultBasedOnOutcomeFromNexus(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, @Nonnull List layers, Boolean optional, boolean outcome) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, NullPointerException, IOException, ParseException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Lab does not exist: " + lab.toString()); + } + return nexusService.getLastResultBasedOnOutcome(name, version, siloText, layers, optional, outcome); + } + + public List getBasedOnDateFromNexus(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, @Nonnull Date date) + throws JsonParseException, JsonMappingException, IOException, ParseException, KeyManagementException, + ClientHandlerException, UniformInterfaceException, NoSuchAlgorithmException, NullPointerException { + String siloText = null; + for (LabSilo silo : siloService.getSilos()) { + if (silo.getLab().getLab().equals(lab)) { + siloText = silo.getSilo(); + } + } + if (siloText == null) { + throw new IllegalArgumentException("Lab does not exist: " + lab.toString()); + } + return nexusService.getResults(name, version, siloText, date); + } + + public Set getLabsFromDb() { + Set labs = new HashSet(); + for (ValidationDbTestResult result : dbAdapter.getValidationTestResults()) { + labs.add(result.getLab().getLab()); + } + return labs; + } + + public Set getBlueprintNamesOfLabFromDb(Lab lab) { + Set blueprintNames = new HashSet(); + for (ValidationDbTestResult result : dbAdapter.getValidationTestResults()) { + if (result.getLab().getLab().equals(lab)) { + blueprintNames.add(result.getBlueprintName()); + } + } + return blueprintNames; + } + + public Set getBlueprintVersionsFromDb(String name, Lab lab) { + Set blueprintVersions = new HashSet(); + for (ValidationDbTestResult result : dbAdapter.getValidationTestResults()) { + if (result.getLab().getLab().equals(lab) && result.getBlueprintName().equals(name)) { + blueprintVersions.add(result.getVersion()); + } + } + return blueprintVersions; + } + + public ValidationNexusTestResult getResults(@Nonnull String submissionId) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, NullPointerException, ParseException { + SubmissionData submissionData = submissionService.getSubmissionData(submissionId); + ValidationNexusTestResult vNexusResult = dbAdapter.readResultFromDb(submissionId); + return vNexusResult == null + ? this.getResultFromNexus(submissionData.getValidationNexusTestResult().getBlueprintName(), + submissionData.getValidationNexusTestResult().getVersion(), + submissionData.getTimeslot().getLab().getLab(), + submissionData.getValidationNexusTestResult().getTimestamp()) + : vNexusResult; + } + + public ValidationNexusTestResult getResult(@Nonnull String name, @Nonnull String version, @Nonnull Lab lab, + @Nonnull String timestamp) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, NullPointerException, IOException, ParseException { + LabInfo actualLabInfo = labService.getLab(lab); + if (actualLabInfo == null) { + return null; + } + ValidationNexusTestResult vNexusResult = dbAdapter.readResultFromDb(lab, timestamp); + return vNexusResult == null ? this.getResultFromNexus(name, version, lab, timestamp) : vNexusResult; + } + + public ValidationNexusTestResult getLastResultBasedOnOutcome(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, Boolean allLayers, Boolean optional, boolean outcome) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, NullPointerException, ParseException { + LabInfo actualLabInfo = labService.getLab(lab); + if (actualLabInfo == null) { + return null; + } + List vNexusResults = dbAdapter.readResultFromDb(name, version, lab, null, allLayers, + optional, outcome); + if (vNexusResults != null) { + vNexusResults.removeIf(entry -> entry.getDateOfStorage() == null); + DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + Collections.sort(vNexusResults, new Comparator() { + @Override + public int compare(ValidationNexusTestResult vNexusResult1, ValidationNexusTestResult vNexusResult2) { + try { + return dateFormat.parse(vNexusResult2.getDateOfStorage()) + .compareTo(dateFormat.parse(vNexusResult1.getDateOfStorage())); + } catch (ParseException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when parsing date. " + UserUtils.getStackTrace(e)); + return 0; + } + } + }); + return vNexusResults.get(0); + } + return this.getLastResultBasedOnOutcomeFromNexus(name, version, lab, allLayers, optional, outcome); + } + + public ValidationNexusTestResult getLastResultBasedOnOutcome(@Nonnull String name, @Nonnull String version, + @Nonnull Lab lab, List layers, Boolean optional, boolean outcome) + throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, + UniformInterfaceException, NoSuchAlgorithmException, IOException, NullPointerException, ParseException { + LabInfo actualLabInfo = labService.getLab(lab); + if (actualLabInfo == null) { + return null; + } + List vNexusResults = dbAdapter.readResultFromDb(name, version, lab, layers, null, + optional, outcome); + if (vNexusResults != null) { + vNexusResults.removeIf(entry -> entry.getDateOfStorage() == null); + DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + Collections.sort(vNexusResults, new Comparator() { + @Override + public int compare(ValidationNexusTestResult vNexusResult1, ValidationNexusTestResult vNexusResult2) { + try { + return dateFormat.parse(vNexusResult2.getDateOfStorage()) + .compareTo(dateFormat.parse(vNexusResult1.getDateOfStorage())); + } catch (ParseException e) { + LOGGER.error(EELFLoggerDelegate.errorLogger, + "Error when parsing date. " + UserUtils.getStackTrace(e)); + return 0; + } + } + }); + return vNexusResults.get(0); + } + return this.getLastResultBasedOnOutcomeFromNexus(name, version, lab, layers, optional, outcome); + } + +} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/JenkinsJobNotificationService.java b/ui/src/main/java/org/akraino/validation/ui/service/JenkinsJobNotificationService.java index c2482b2..429696a 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/JenkinsJobNotificationService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/JenkinsJobNotificationService.java @@ -15,12 +15,16 @@ */ package org.akraino.validation.ui.service; -import org.akraino.validation.ui.conf.UiUtils; -import org.akraino.validation.ui.data.BlueprintLayer; +import java.util.ArrayList; +import java.util.List; + +import org.akraino.validation.ui.client.nexus.resources.ValidationNexusTestResult; +import org.akraino.validation.ui.dao.ValidationTestResultDAO; import org.akraino.validation.ui.data.JnksJobNotify; import org.akraino.validation.ui.data.SubmissionStatus; import org.akraino.validation.ui.entity.LabSilo; import org.akraino.validation.ui.entity.Submission; +import org.akraino.validation.ui.entity.ValidationDbTestResult; import org.akraino.validation.ui.service.utils.SubmissionHelper; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.springframework.beans.factory.annotation.Autowired; @@ -37,11 +41,20 @@ public class JenkinsJobNotificationService { private SubmissionHelper submissionHelper; @Autowired - private SubmissionService submissionService; + private DbSubmissionAdapter submissionService; @Autowired private SiloService siloService; + @Autowired + private DbResultAdapter dbAdapter; + + @Autowired + private IntegratedResultService iService; + + @Autowired + private ValidationTestResultDAO vTestResultDAO; + public void handle(JnksJobNotify jnksJobNotify) throws Exception { String jenkinsJobName = System.getenv("JENKINS_JOB_NAME"); if (!jenkinsJobName.equals(jnksJobNotify.getName())) { @@ -59,20 +72,24 @@ public class JenkinsJobNotificationService { } } if (siloText == null) { - throw new Exception("Could not retrieve silo of the selected lab : " + throw new IllegalArgumentException("Could not retrieve silo of the selected lab : " + submission.getTimeslot().getLab().getLab().toString()); } - - String nexusUrl = UiUtils.NEXUS_URL + "/" + siloText + "/job/" + System.getenv("JENKINS_JOB_NAME") + "/" - + String.valueOf(jnksJobNotify.getbuildNumber() + "/results"); - if (!submission.getBlueprintInstanceForValidation().getLayer().equals(BlueprintLayer.All)) { - nexusUrl = nexusUrl + "/" + submission.getBlueprintInstanceForValidation().getLayer().name().toLowerCase(); - } - submission.setNexusResultUrl(nexusUrl); LOGGER.info(EELFLoggerDelegate.applicationLogger, "Updating submission with id: " + submission.getSubmissionId()); submission.setSubmissionStatus(SubmissionStatus.Completed); submissionHelper.saveSubmission(submission); + ValidationDbTestResult vDbResult = vTestResultDAO.getValidationTestResult(submission); + if (vDbResult != null) { + ValidationNexusTestResult vNexusResult = iService.getResult(vDbResult.getBlueprintName(), + vDbResult.getVersion(), vDbResult.getLab().getLab(), jnksJobNotify.getTimestamp()); + if (vNexusResult != null) { + List vNexusResults = new ArrayList(); + vNexusResults.add(vNexusResult); + dbAdapter.storeResultInDb(vNexusResults); + } + } + dbAdapter.updateTimestamp(jnksJobNotify); } } diff --git a/ui/src/main/java/org/akraino/validation/ui/service/LabService.java b/ui/src/main/java/org/akraino/validation/ui/service/LabService.java index 8dfc15e..4280f37 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/LabService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/LabService.java @@ -18,6 +18,7 @@ package org.akraino.validation.ui.service; import java.util.List; import org.akraino.validation.ui.dao.LabDAO; +import org.akraino.validation.ui.data.Lab; import org.akraino.validation.ui.entity.LabInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -31,15 +32,15 @@ public class LabService { private LabDAO labDAO; public void saveLab(LabInfo lab) { - labDAO.saveOrUpdate(lab); + } + public LabInfo getLab(Lab lab) { + return labDAO.getLab(lab); } public List getLabs() { - return labDAO.getLabs(); - } public void deleteAll() { diff --git a/ui/src/main/java/org/akraino/validation/ui/service/ResultService.java b/ui/src/main/java/org/akraino/validation/ui/service/ResultService.java deleted file mode 100644 index b189dba..0000000 --- a/ui/src/main/java/org/akraino/validation/ui/service/ResultService.java +++ /dev/null @@ -1,112 +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. - */ -package org.akraino.validation.ui.service; - -import java.io.IOException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.List; - -import org.akraino.validation.ui.client.jenkins.JenkinsExecutorClient; -import org.akraino.validation.ui.client.jenkins.resources.QueueJobItem; -import org.akraino.validation.ui.client.jenkins.resources.QueueJobItem.Executable; -import org.akraino.validation.ui.client.nexus.NexusExecutorClient; -import org.akraino.validation.ui.client.nexus.resources.WrapperRobotTestResult; -import org.akraino.validation.ui.conf.UiUtils; -import org.akraino.validation.ui.data.BlueprintLayer; -import org.akraino.validation.ui.entity.LabSilo; -import org.akraino.validation.ui.entity.Submission; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.UniformInterfaceException; - -@Service -public class ResultService { - - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ResultService.class); - - @Autowired - private SubmissionService submissionService; - - @Autowired - private SiloService siloService; - - @Deprecated - public URL getNexusResultUrl(Submission submission) throws Exception { - - String url = System.getenv("JENKINS_URL"); - String userName = System.getenv("JENKINS_USERNAME"); - String password = System.getenv("JENKINS_USER_PASSWORD"); - - Executable executable = null; - while (executable == null) { - JenkinsExecutorClient client; - client = JenkinsExecutorClient.getInstance(userName, password, url); - QueueJobItem queueJobItem = client.getQueueJobItem(new URL(submission.getJenkinsQueueJobItemUrl())); - executable = queueJobItem.getExecutable(); - Thread.sleep(2000); - } - String siloText = null; - for (LabSilo silo : siloService.getSilos()) { - if (silo.getLab().getLab().equals(submission.getTimeslot().getLab().getLab())) { - siloText = silo.getSilo(); - } - } - if (siloText == null) { - throw new Exception("Could not retrieve silo of the selected lab : " - + submission.getTimeslot().getLab().getLab().toString()); - } - String nexusUrl = UiUtils.NEXUS_URL + "/" + siloText + "/job/" + System.getenv("JENKINS_JOB_NAME") + "/" - + String.valueOf(executable.getNumber() + "/results"); - if (!submission.getBlueprintInstanceForValidation().getLayer().equals(BlueprintLayer.All)) { - nexusUrl = nexusUrl + "/" + submission.getBlueprintInstanceForValidation().getLayer().name().toLowerCase(); - } - return new URL(nexusUrl); - } - - public List getRobotTestResults(String submissionId) - throws JsonParseException, JsonMappingException, KeyManagementException, ClientHandlerException, - UniformInterfaceException, NoSuchAlgorithmException, IOException { - Submission submission = submissionService.getSubmission(submissionId); - if (submission == null) { - LOGGER.info(EELFLoggerDelegate.applicationLogger, "Requested submission does not exist"); - return null; - } - String nexusUrl = submission.getNexusResultUrl(); - String urlLastpart = nexusUrl.substring(nexusUrl.lastIndexOf('/') + 1); - if (blueprintLayerContains(urlLastpart.substring(0, 1).toUpperCase() + urlLastpart.substring(1))) { - nexusUrl = nexusUrl.substring(0, nexusUrl.lastIndexOf(urlLastpart) - 1); - } - NexusExecutorClient client = new NexusExecutorClient(nexusUrl); - return client.getRobotTestResults(); - } - - private boolean blueprintLayerContains(String layer) { - for (BlueprintLayer blueprintLayer : BlueprintLayer.values()) { - if (blueprintLayer.name().equals(layer)) { - return true; - } - } - return false; - } - -} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/SiloService.java b/ui/src/main/java/org/akraino/validation/ui/service/SiloService.java index 16ebe30..23332d7 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/SiloService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/SiloService.java @@ -31,15 +31,11 @@ public class SiloService { private SiloDAO siloDAO; public void saveSilo(LabSilo silo) { - siloDAO.saveOrUpdate(silo); - } public List getSilos() { - return siloDAO.getSilos(); - } public void deleteAll() { diff --git a/ui/src/main/java/org/akraino/validation/ui/service/SubmissionService.java b/ui/src/main/java/org/akraino/validation/ui/service/SubmissionService.java deleted file mode 100644 index ccf4087..0000000 --- a/ui/src/main/java/org/akraino/validation/ui/service/SubmissionService.java +++ /dev/null @@ -1,154 +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. - */ -package org.akraino.validation.ui.service; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.CompletableFuture; - -import org.akraino.validation.ui.client.jenkins.JenkinsExecutorClient; -import org.akraino.validation.ui.client.jenkins.resources.Parameter; -import org.akraino.validation.ui.client.jenkins.resources.Parameters; -import org.akraino.validation.ui.conf.UiUtils; -import org.akraino.validation.ui.dao.SubmissionDAO; -import org.akraino.validation.ui.data.SubmissionStatus; -import org.akraino.validation.ui.entity.Submission; -import org.akraino.validation.ui.service.utils.PrioritySupplier; -import org.akraino.validation.ui.service.utils.SubmissionHelper; -import org.apache.commons.httpclient.HttpException; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.UniformInterfaceException; - -@Service -@Transactional -public class SubmissionService { - - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(SubmissionService.class); - - @Autowired - private SubmissionDAO submissionDAO; - - @Autowired - private SubmissionHelper submissionHelper; - - public Submission saveSubmission(Submission submission) { - submission.setSubmissionStatus(SubmissionStatus.Submitted); - submissionDAO.saveOrUpdate(submission); - - JenkinsTriggerSubmissionJob task = new JenkinsTriggerSubmissionJob(submission); - CompletableFuture completableFuture = - CompletableFuture.supplyAsync(new PrioritySupplier<>(1, task::execute), UiUtils.executorService); - completableFuture.thenAcceptAsync(result -> this.callbackNotify(result)); - - return submission; - } - - public List getSubmissions() { - return submissionDAO.getSubmissions(); - } - - public Submission getSubmission(String submissionId) { - return submissionDAO.getSubmission(Integer.valueOf(submissionId)); - } - - public void deleteSubmission(Integer submissionId) { - submissionDAO.deleteSubmission(submissionId); - } - - public void deleteAll() { - submissionDAO.deleteAll(); - } - - private void callbackNotify(Submission submission) { - if (submission == null) { - return; - } - submission.setSubmissionStatus(SubmissionStatus.Running); - submissionHelper.saveSubmission(submission); - } - - private class JenkinsTriggerSubmissionJob { - - private Submission submission; - - public JenkinsTriggerSubmissionJob(Submission submission) { - this.submission = submission; - } - - public Submission execute() { - String url = System.getenv("JENKINS_URL"); - String userName = System.getenv("JENKINS_USERNAME"); - String userPassword = System.getenv("JENKINS_USER_PASSWORD"); - String jobName = System.getenv("JENKINS_JOB_NAME"); - List listOfParameters = new ArrayList(); - Parameters parameters = new Parameters(); - Parameter parameter = new Parameter(); - parameter.setName("SUBMISSION_ID"); - parameter.setValue(String.valueOf(submission.getSubmissionId())); - listOfParameters.add(parameter); - parameter = new Parameter(); - parameter.setName("BLUEPRINT"); - parameter.setValue( - submission.getBlueprintInstanceForValidation().getBlueprint().getBlueprintName().toLowerCase()); - listOfParameters.add(parameter); - parameter = new Parameter(); - parameter.setName("LAYER"); - parameter.setValue(submission.getBlueprintInstanceForValidation().getLayer().name().toLowerCase()); - listOfParameters.add(parameter); - parameter = new Parameter(); - parameter.setName("VERSION"); - parameter.setValue(submission.getBlueprintInstanceForValidation().getVersion().toLowerCase()); - listOfParameters.add(parameter); - parameter = new Parameter(); - parameter.setName("UI_IP"); - Random random = new Random(); - String localIP = null; - try (final DatagramSocket socket = new DatagramSocket()) { - socket.connect(InetAddress.getByName(random.nextInt(256) + "." + random.nextInt(256) + "." - + random.nextInt(256) + "." + random.nextInt(256)), 10002); - localIP = socket.getLocalAddress().getHostAddress(); - parameter.setValue(localIP); - listOfParameters.add(parameter); - parameters.setParameter(listOfParameters); - JenkinsExecutorClient client; - client = JenkinsExecutorClient.getInstance(userName, userPassword, url); - submission.setJnksQueueJobItemUrl(client.postJobWithQueryParams(jobName, parameters).toString()); - return submission; - } catch (SocketException | UnknownHostException | KeyManagementException | HttpException - | ClientHandlerException | UniformInterfaceException | MalformedURLException - | NoSuchAlgorithmException e) { - LOGGER.error(EELFLoggerDelegate.errorLogger, - "Error when triggering Jenkins job. " + UserUtils.getStackTrace(e)); - return null; - } - } - } - -} diff --git a/ui/src/main/java/org/akraino/validation/ui/service/TimeslotService.java b/ui/src/main/java/org/akraino/validation/ui/service/TimeslotService.java index 8df150d..6445d7f 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/TimeslotService.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/TimeslotService.java @@ -31,15 +31,11 @@ public class TimeslotService { private TimeslotDAO timeslotDAO; public void saveTimeslot(Timeslot timeslot) { - timeslotDAO.saveOrUpdate(timeslot); - } public List getTimeslots() { - return timeslotDAO.getTimeslots(); - } public void deleteAll() { diff --git a/ui/src/main/java/org/akraino/validation/ui/service/utils/SubmissionHelper.java b/ui/src/main/java/org/akraino/validation/ui/service/utils/SubmissionHelper.java index 8e45d73..8f5bf7e 100644 --- a/ui/src/main/java/org/akraino/validation/ui/service/utils/SubmissionHelper.java +++ b/ui/src/main/java/org/akraino/validation/ui/service/utils/SubmissionHelper.java @@ -33,4 +33,8 @@ public class SubmissionHelper { return submission; } + public Submission getSubmission(int submissionId) { + return submissionDAO.getSubmission(submissionId); + } + } diff --git a/ui/src/main/resources/logback.xml b/ui/src/main/resources/logback.xml index 9c7102e..391f5a9 100644 --- a/ui/src/main/resources/logback.xml +++ b/ui/src/main/resources/logback.xml @@ -46,7 +46,7 @@ - + diff --git a/ui/src/main/resources/music.properties b/ui/src/main/resources/music.properties index f5c824a..ed2de35 100644 --- a/ui/src/main/resources/music.properties +++ b/ui/src/main/resources/music.properties @@ -13,8 +13,8 @@ music.cleanup.frequency = 6 #how old of session need to be cleaned up (hour) music.cleanup.threshold = 10 music.enable = false -cassandra.host=135.197.226.103 -zookeeper.host=135.197.226.103, 135.197.226.108, 135.197.226.119 +cassandra.host=localhost +zookeeper.host=localhost1,localhost2,localhost3 cassandra.user=cassandra cassandra.password=cassandra diff --git a/ui/src/main/resources/portal.properties b/ui/src/main/resources/portal.properties index 5434599..b6c0dc1 100644 --- a/ui/src/main/resources/portal.properties +++ b/ui/src/main/resources/portal.properties @@ -68,3 +68,15 @@ ueb_listeners_enable = false # If key ueb_listeners_enable is set to false, # then only the ueb_app_key is required. ueb_app_key = REPLACE-ME-UEB-APP-KEY-EPSDK-APP-OS + +# Name of the akraino database +akraino_database_name = akraino + +# Nexus URL +nexus_url = https://nexus.akraino.org/content/sites/logs + +# Sleep time of threads in milliseconds +thread_sleep = 5000 + +# Number of last timestamps to retrieve proactively from Nexus +no_last_timestamps = 50 \ No newline at end of file diff --git a/ui/src/main/webapp/WEB-INF/conf/system.properties b/ui/src/main/webapp/WEB-INF/conf/system.properties index 6276357..fa26104 100644 --- a/ui/src/main/webapp/WEB-INF/conf/system.properties +++ b/ui/src/main/webapp/WEB-INF/conf/system.properties @@ -39,7 +39,7 @@ decryption_key = AGLDdG4D04BKm2IxIWEr8o== #Mysql db.driver = org.mariadb.jdbc.Driver -db.userName = root +db.userName = akraino db.encrypt_flag = false db.hib.dialect = org.hibernate.dialect.MySQLDialect db.min_pool_size = 5 diff --git a/ui/src/main/webapp/WEB-INF/defs/definitions.xml b/ui/src/main/webapp/WEB-INF/defs/definitions.xml index ec0ec0d..f64ea8f 100644 --- a/ui/src/main/webapp/WEB-INF/defs/definitions.xml +++ b/ui/src/main/webapp/WEB-INF/defs/definitions.xml @@ -17,13 +17,25 @@ - + - + - + + + + + + + + + diff --git a/ui/src/main/webapp/WEB-INF/jsp/login.jsp b/ui/src/main/webapp/WEB-INF/jsp/login.jsp index c5b43e0..b1554a7 100644 --- a/ui/src/main/webapp/WEB-INF/jsp/login.jsp +++ b/ui/src/main/webapp/WEB-INF/jsp/login.jsp @@ -23,92 +23,105 @@ limitations under the License. %> - - - - - Login - - - - -
-
-
${model.error}
-
-
-
-
-
-
- - - + + + + + Login + + + + + +
+
+
${model.error}
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/WEB-INF/jsp/login_external.jsp b/ui/src/main/webapp/WEB-INF/jsp/login_external.jsp index 9d389d0..a007d05 100644 --- a/ui/src/main/webapp/WEB-INF/jsp/login_external.jsp +++ b/ui/src/main/webapp/WEB-INF/jsp/login_external.jsp @@ -23,92 +23,105 @@ limitations under the License. %> - - - - - - - - - -
-
-
${model.error}
-
-
-
-
-
-
- - - + + + + + + + + + + + +
+
+
${model.error}
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/WEB-INF/jsp/logout.jsp b/ui/src/main/webapp/WEB-INF/jsp/logout.jsp new file mode 100644 index 0000000..b92ceb3 --- /dev/null +++ b/ui/src/main/webapp/WEB-INF/jsp/logout.jsp @@ -0,0 +1,60 @@ +<%-- + ============LICENSE_START========================================== + ONAP Portal SDK + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + =================================================================== + + Unless otherwise specified, all software contained herein is licensed + under the Apache License, Version 2.0 (the “License”); + you may not use this software 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. + + Unless otherwise specified, all documentation contained herein is licensed + under the Creative Commons License, Attribution 4.0 Intl. (the “License”); + you may not use this documentation except in compliance with the License. + You may obtain a copy of the License at + + https://creativecommons.org/licenses/by/4.0/ + + Unless required by applicable law or agreed to in writing, documentation + 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. + + ============LICENSE_END============================================ + + + --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ page import="java.net.URLEncoder"%> +<%@ page import="org.onap.portalsdk.core.util.SystemProperties"%> + +<%-- Redirected because we can't set the welcome page to a virtual URL. --%> +<%-- Forward to the intended start page to reduce frustration for new users. --%> + +<% + String scheme = request.getScheme() + "://"; + String servername = request.getServerName(); + Integer urlPort = request.getServerPort(); + String contextPath = request.getContextPath(); + String htmFile = "/login.htm"; + request.getSession().invalidate(); + String redirectURL = ""; + redirectURL = redirectURL + scheme + servername; + if ((urlPort != null) && (urlPort.intValue() != 80) && (urlPort.intValue() != 443) + && (urlPort.intValue() != -1)) { + redirectURL += ":" + urlPort; + } + redirectURL += contextPath + htmFile; +%> + \ No newline at end of file diff --git a/ui/src/main/webapp/WEB-INF/web.xml b/ui/src/main/webapp/WEB-INF/web.xml index 92a2d59..2071632 100644 --- a/ui/src/main/webapp/WEB-INF/web.xml +++ b/ui/src/main/webapp/WEB-INF/web.xml @@ -12,7 +12,7 @@ xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"> - AECBlueprintValidationUI + bluvalui diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/App.Services.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/App.Services.js deleted file mode 100644 index 8fa4ce6..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/App.Services.js +++ /dev/null @@ -1,108 +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. - */ - -var services = angular.module('App.Services', [ 'App.Config' ]); - -services.factory('restAPISvc', [ - '$http', - 'appContext', - function($http, appContext) { - var svc = []; - svc.getRestAPI = function(path, cb) { - return $http({ - method : 'GET', - url : appContext + path, - headers : { - 'Content-Type' : "application/json", - 'Accept' : "application/json" - } - }).then( - function(response) { - if (response.status == 200) { - cb(response.data); - } else { - /* eslint-disable no-console */ - console.log("Get REST API error: " - + response.statusText); - /* eslint-enable no-console */ - cb(null); - } - }, - function(error) { - /* eslint-disable no-console */ - console.log("Get REST API error: " - + error.statusText); - /* eslint-enable no-console */ - cb(null); - }); - }; - svc.postRestAPI = function(path, json, cb) { - return $http({ - method : 'POST', - url : appContext + path, - headers : { - 'Content-Type' : "application/json", - 'Accept' : "application/json" - }, - data : json - }).then( - function(response) { - if (response.status == 200 - || response.status == 201) { - cb(response.data); - } else { - /* eslint-disable no-console */ - console.log("Post REST API error: " - + response.statusText); - /* eslint-enable no-console */ - cb(null); - } - }, - function(error) { - /* eslint-disable no-console */ - console.log("Post REST API error: " - + error.statusText); - /* eslint-enable no-console */ - cb(null); - }); - }; - svc.deleteRestAPI = function(path, json) { - return $http({ - method : 'DELETE', - url : appContext + path, - headers : { - 'Content-Type' : "application/json", - 'Accept' : "application/json" - }, - data : json - }).then( - function(response) { - if (response.status !== 200) { - /* eslint-disable no-console */ - console.log("Delete REST API error: " - + response.statusText); - /* eslint-enable no-console */ - } - }, - function(error) { - /* eslint-disable no-console */ - console.log("Delete REST API error: " - + error.statusText); - /* eslint-enable no-console */ - }); - }; - return svc; - } ]); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js deleted file mode 100644 index 27d4a14..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissionsController.js +++ /dev/null @@ -1,36 +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. - */ - -var app = angular.module('AECCommittedSubmissions'); - -app.controller('AECCommittedSubmissionsController', function($scope, - restAPISvc, $interval, refreshPeriod) { - - restAPISvc.getRestAPI("/api/submission/", function(data) { - $scope.submissions = data; - }); - - $scope.refreshCommittedSubmissions = function() { - restAPISvc.getRestAPI("/api/submission/", function(data) { - $scope.submissions = data; - }); - } - - $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 deleted file mode 100644 index b2e3838..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html +++ /dev/null @@ -1,327 +0,0 @@ - -
- - - -

Committed Submissions

- -
- -
- -
- -
- - -
- -
- -
- -
- -
- - -
- - - - - - - - - - - - - - - - - - - - - - - -
Id Status Blueprint VersionLayer Desired Timeslot Url of result 
{{ - submission.submissionId }}{{ - submission.submissionStatus }}{{ - submission.blueprintInstanceForValidation.blueprint.blueprintName - }}{{ - submission.blueprintInstanceForValidation.version }}{{ - submission.blueprintInstanceForValidation.layer }}Lab: - {{ submission.timeslot.lab.lab }} Start date and time: {{ - submission.timeslot.startDateTime }} - {{ - submission.nexusResultUrl }}
- -
-
-
- - - -
\ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js deleted file mode 100644 index ebad5be..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionIdController.js +++ /dev/null @@ -1,130 +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. - */ - -var app = angular.module('AECGetBySubmissionId'); -app - .controller( - 'AECGetBySubmissionIdController', - function($scope, restAPISvc) { - - initialize(); - - function initialize() { - $scope.loading = false; - $scope.showResults = false; - $scope.results = []; - $scope.resultsLayers = []; - $scope.resultsLayerTestSuitesNames = []; - $scope.selectedRobotTestResult = []; - restAPISvc - .getRestAPI( - "/api/submission/", - function(data) { - $scope.submissions = data; - $scope.submissionsForDisplay = []; - angular - .forEach( - $scope.submissions, - function( - submissionData) { - 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); - } - }); - }); - } - $scope.selectedSubmissionChange = function( - selectedSubmission) { - $scope.results = []; - $scope.resultsLayers = []; - $scope.resultsLayerTestSuitesNames = []; - $scope.selectedRobotTestResult = []; - $scope.loading = true; - $scope.showResults = false; - var id = selectedSubmission.substring( - selectedSubmission.indexOf("id:") + 4, - selectedSubmission.indexOf("blueprint") - 1); - restAPISvc - .getRestAPI( - "/api/results/getBySubmissionId/" + id, - function(data) { - $scope.loading = false; - if (data !== undefined) { - $scope.results = data; - angular - .forEach( - $scope.results, - function(result) { - $scope.resultsLayers - .push(result.blueprintLayer); - }); - $scope.showResults = true; - } else { - confirm("Error when committing the submission"); - } - }); - } - - $scope.selectedResultsLayerChange = function(selectedLayer) { - $scope.resultsLayerTestSuitesNames = []; - $scope.robotTestResults = []; - $scope.selectedRobotTestResult = []; - var selectedLayerResult = []; - angular.forEach($scope.results, function(result) { - if (result.blueprintLayer === selectedLayer) { - selectedLayerResult = result; - } - }); - $scope.robotTestResults = selectedLayerResult.robotTestResults; - angular.forEach($scope.robotTestResults, function( - robotTestResult) { - $scope.resultsLayerTestSuitesNames - .push(robotTestResult.name); - }); - } - - $scope.selectedTestSuitesNameChange = function( - selectedTestSuiteName) { - angular - .forEach( - $scope.robotTestResults, - function(robotTestResult) { - if (robotTestResult.name.trim() === selectedTestSuiteName - .trim()) { - $scope.selectedRobotTestResult = robotTestResult; - } - }); - } - - }); diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html deleted file mode 100644 index 8d6324c..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html +++ /dev/null @@ -1,388 +0,0 @@ - - -
- - -

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:

-
- -
-
- -


- -
-
-

-
-

- General 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}} -
-
-
-
-
-
- -

-
-

- 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/GetBySubmissionId/Route.js b/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/Route.js deleted file mode 100644 index 58c09fd..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/Route.js +++ /dev/null @@ -1,9 +0,0 @@ -appDS2 - .config(function($routeProvider) { - $routeProvider - - .otherwise({ - templateUrl : 'app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionIdTemplate.html', - controller : "AECGetBySubmissionIdController" - }); - }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmissionTemplate.html b/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmissionTemplate.html deleted file mode 100644 index a84fa05..0000000 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmissionTemplate.html +++ /dev/null @@ -1,73 +0,0 @@ - - -
-
-

New Submission

-

Submission form

- -
-
- -
-
-
- -
-
- -
-
-
- -
-
- -
-
-
- - -
-
- -
-
-
- -
- -
-
-
diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/App.Config.js b/ui/src/main/webapp/app/BluvalUI/App.Config.js similarity index 84% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/App.Config.js rename to ui/src/main/webapp/app/BluvalUI/App.Config.js index 6186a2b..8ae0487 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/App.Config.js +++ b/ui/src/main/webapp/app/BluvalUI/App.Config.js @@ -15,5 +15,5 @@ */ var config_module = angular.module('App.Config', []); -config_module.constant('appContext', '/AECBlueprintValidationUI'); -config_module.constant('refreshPeriod', '5000'); // in msecs +config_module.constant('appContext', '/bluvalui'); +config_module.constant('refreshPeriod', '12000'); // in msecs diff --git a/ui/src/main/webapp/app/BluvalUI/App.Services.js b/ui/src/main/webapp/app/BluvalUI/App.Services.js new file mode 100644 index 0000000..b5123e1 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/App.Services.js @@ -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. + */ + +var services = angular.module('App.Services', ['App.Config']); + +services.factory('restAPISvc', [ + '$http', + 'appContext', + function ($http, appContext) { + var svc = []; + svc.getRestAPI = function (path, cb) { + return $http({ + method: 'GET', + url: appContext + path, + headers: { + 'Content-Type': "application/json", + 'Accept': "application/json" + } + }).then( + function (response) { + if (response.status == 200) { + cb(response.data); + } else { + /* eslint-disable no-console */ + console.log("Get REST API error: " + + response.statusText); + /* eslint-enable no-console */ + cb(null); + } + }, + function (error) { + /* eslint-disable no-console */ + console.log("Get REST API error: " + + error.statusText); + /* eslint-enable no-console */ + cb(null); + }); + }; + svc.postRestAPI = function (path, json, cb) { + return $http({ + method: 'POST', + url: appContext + path, + headers: { + 'Content-Type': "application/json", + 'Accept': "application/json" + }, + data: json + }).then( + function (response) { + if (response.status == 200 + || response.status == 201) { + cb(response.data); + } else { + /* eslint-disable no-console */ + console.log("Post REST API error: " + + response.statusText); + /* eslint-enable no-console */ + cb(null); + } + }, + function (error) { + /* eslint-disable no-console */ + console.log("Post REST API error: " + + error.statusText); + /* eslint-enable no-console */ + cb(null); + }); + }; + svc.deleteRestAPI = function (path, json) { + return $http({ + method: 'DELETE', + url: appContext + path, + headers: { + 'Content-Type': "application/json", + 'Accept': "application/json" + }, + data: json + }).then( + function (response) { + if (response.status !== 200) { + /* eslint-disable no-console */ + console.log("Delete REST API error: " + + response.statusText); + /* eslint-enable no-console */ + } + }, + function (error) { + /* eslint-disable no-console */ + console.log("Delete REST API error: " + + error.statusText); + /* eslint-enable no-console */ + }); + }; + return svc; + }]); + +services.factory("sharedContext", function () { + var context = []; + var addData = function (key, value) { + var data = { + key: key, + value: value + }; + context.push(data); + } + var getData = function (key) { + var data = []; + angular + .forEach( + context, + function (pair) { + if (pair.key === key) { + data = pair.value; + } + }); + return data; + } + + return { + addData: addData, + getData: getData + } +}); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.Services.js b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.Services.js new file mode 100644 index 0000000..dd4f699 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.Services.js @@ -0,0 +1,99 @@ +/* + * 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. + */ + +var app = angular.module('CommittedSubmissions'); + +app + .factory( + 'committedSubmissionsSvc', + [ function() { + var svc = []; + svc.getLayer = function(validationNexusTestResult) { + if (validationNexusTestResult.allLayers) { + return "all"; + } + var layers = []; + angular + .forEach( + validationNexusTestResult.wRobotNexusTestResults, + function(result) { + layers.push(result.blueprintLayer); + }); + return layers; + }; + svc.getResultUrl = function(submissionData) { + if (submissionData.status !== "Completed") { + return null; + } + if (!submissionData.validationNexusTestResult.wRobotNexusTestResults) { + return null; + } + if (submissionData.validationNexusTestResult.wRobotNexusTestResults.length === 0) { + return null; + } + var resultExistence = false; + angular + .forEach( + submissionData.validationNexusTestResult.wRobotNexusTestResults, + function(result) { + if (result.robotTestResults + && result.robotTestResults.length > 0) { + resultExistence = true; + } + }); + if (resultExistence) { + return "https://nexus.akraino.org/content/sites/logs/" + + submissionData.validationNexusTestResult.silo + + "/" + + submissionData.validationNexusTestResult.blueprintName + + "/" + + submissionData.validationNexusTestResult.version + + "/" + + submissionData.validationNexusTestResult.timestamp + + "/"; + } + return null; + }; + svc.mapResult = function(validationNexusTestResult) { + if (!validationNexusTestResult.timestamp) { + return null; + } + if (!validationNexusTestResult.wRobotNexusTestResults) { + return null; + } + if (validationNexusTestResult.wRobotNexusTestResults.length === 0) { + return null; + } + var resultExistence = false; + angular + .forEach( + validationNexusTestResult.wRobotNexusTestResults, + function(result) { + if (result.robotTestResults + && result.robotTestResults.length > 0) { + resultExistence = true; + } + }); + if (resultExistence) { + if (validationNexusTestResult.result === true) { + return 'SUCCESS'; + } + return 'FAILURE' + } + return null; + }; + return svc; + } ]); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.html b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.html new file mode 100644 index 0000000..3352960 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.html @@ -0,0 +1,189 @@ + + + + + + + + + + +Committed Submissions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionId.js b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.js similarity index 84% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionId.js rename to ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.js index e4d0b89..b6edf3b 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/AECGetBySubmissionId.js +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissions.js @@ -14,6 +14,6 @@ * limitations under the License. */ -var appDS2 = angular.module("AECGetBySubmissionId", [ 'ngRoute', 'ngMessages', +var appDS2 = angular.module("CommittedSubmissions", [ 'ngRoute', 'ngMessages', 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', - 'ui.bootstrap.modal', 'App.Services' ]); \ No newline at end of file + 'ui.bootstrap.modal', 'App.Config', 'App.Services', 'ngTable' ]); diff --git a/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsController.js b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsController.js new file mode 100644 index 0000000..8f7a8a3 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsController.js @@ -0,0 +1,59 @@ +/* + * 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. + */ + +var app = angular.module('CommittedSubmissions'); + +app.controller('CommittedSubmissionsController', function($scope, restAPISvc, + $interval, refreshPeriod, committedSubmissionsSvc, NgTableParams, + appContext, $window) { + + $scope.getLayer = committedSubmissionsSvc.getLayer; + $scope.getResultUrl = committedSubmissionsSvc.getResultUrl; + $scope.mapResult = committedSubmissionsSvc.mapResult; + + initialize(); + + function initialize() { + restAPISvc.getRestAPI("/api/v1/submission/", function(submissions) { + $scope.submissionDatas = submissions; + var data = submissions; + $scope.tableParams = new NgTableParams({ + page : 1, + count : 5 + }, { + dataset : data + }); + }); + } + + $scope.refreshCommittedSubmissions = function() { + initialize(); + } + + $scope.getValidationResults = function(submissionData) { + if (!submissionData.validationNexusTestResult.timestamp) { + return; + } + $window.location.href = appContext + + "/validationresults#?submissionId=" + + submissionData.submissionId; + } + + $interval(function() { + $scope.refreshCommittedSubmissions(); + }, refreshPeriod); + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsTemplate.html b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsTemplate.html new file mode 100644 index 0000000..cdb6de9 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/CommittedSubmissionsTemplate.html @@ -0,0 +1,73 @@ + +
+ + + +
+

Committed Submissions

+
+ +
+ + + + + + + + + + + + +
{{ + submissionData.submissionId }}Lab: {{ + submissionData.timeslot.lab.lab }} Start date and + time: {{ submissionData.timeslot.startDateTime }} + {{ + submissionData.validationNexusTestResult.blueprintName + }}{{ + submissionData.validationNexusTestResult.version }}{{ + getLayer(submissionData.validationNexusTestResult) + }}{{ + submissionData.validationNexusTestResult.optional}}{{ submissionData.status }}{{getResultUrl(submissionData)}} + +
+
+ +
\ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/Route.js b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/Route.js new file mode 100644 index 0000000..aedc6d9 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/CommittedSubmissions/Route.js @@ -0,0 +1,24 @@ +/* + * 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. + */ + +appDS2 + .config(function ($routeProvider) { + $routeProvider + .otherwise({ + templateUrl: 'app/BluvalUI/CommittedSubmissions/CommittedSubmissionsTemplate.html', + controller: "CommittedSubmissionsController" + }); + }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.html b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.html new file mode 100644 index 0000000..1453020 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.html @@ -0,0 +1,179 @@ + + + + + + + + + + +Get Most Recent Results + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissions.js b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.js similarity index 74% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissions.js rename to ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.js index 9730d6c..eaab0a3 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/AECCommittedSubmissions.js +++ b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDate.js @@ -14,6 +14,7 @@ * limitations under the License. */ -var appDS2 = angular.module("AECCommittedSubmissions", [ 'ngRoute', - 'ngMessages', 'modalServices', 'ngCookies', 'b2b.att', 'gridster', - 'ui.bootstrap', 'ui.bootstrap.modal', 'App.Config', 'App.Services' ]); +var appDS2 = angular.module("GetBasedOnDate", ['ngRoute', 'ngMessages', + 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', + 'ui.bootstrap.modal', 'App.Services', 'App.Config']); + diff --git a/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateController.js b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateController.js new file mode 100644 index 0000000..607634b --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateController.js @@ -0,0 +1,83 @@ +/* + * 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. + */ + +var app = angular.module('GetBasedOnDate'); +app.controller('GetBasedOnDateController', function($scope, restAPISvc, + $window, appContext, $filter) { + + initialize(); + + function initialize() { + $scope.loadingLabs = true; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + restAPISvc.getRestAPI("/api/v1/results/getlabs/", function(data) { + $scope.labs = data; + $scope.loadingLabs = false; + }); + } + + $scope.selectedLabChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = true; + $scope.loadingVersions = false; + $scope.blueprints = []; + $scope.versions = []; + $scope.selectedBlueprint = {}; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintnamesoflab/" + + $scope.selectedLab, function(data) { + $scope.blueprints = data; + $scope.loadingBlueprints = false; + }); + } + + $scope.selectedBlueprintChange = function() { + if (!$scope.selectedLab) { + return; + } + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = true; + $scope.versions = []; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintversions/" + + $scope.selectedBlueprint + "/" + $scope.selectedLab, + function(data) { + $scope.versions = data; + $scope.loadingVersions = false; + }); + } + + $scope.selectedVersionChange = function() { + } + + $scope.get = function() { + if (!$scope.selectedLab || !$scope.selectedBlueprint + || !$scope.selectedVersion || !$scope.selectedDate) { + confirm("You must specify all data fields"); + return; + } + var selectedDate = $filter('date')($scope.selectedDate, "MM-dd-yyyy"); + + $window.location.href = appContext + + "/validationresults#?blueprintName=" + + $scope.selectedBlueprint + "&" + "version=" + + $scope.selectedVersion + "&" + "lab=" + $scope.selectedLab + + "&" + "date=" + selectedDate; + } + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateTemplate.html b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateTemplate.html new file mode 100644 index 0000000..e8240cf --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/GetBasedOnDateTemplate.html @@ -0,0 +1,71 @@ + +
+ +

Get Results Based on Date

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/Route.js b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/Route.js new file mode 100644 index 0000000..007a7f0 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetBasedOnDate/Route.js @@ -0,0 +1,22 @@ +/* + * 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. + */ + +appDS2.config(function($routeProvider) { + $routeProvider.otherwise({ + templateUrl : 'app/BluvalUI/GetBasedOnDate/GetBasedOnDateTemplate.html', + controller : "GetBasedOnDateController" + }); +}); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissions.html b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.html similarity index 58% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissions.html rename to ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.html index 8886182..c2e3afb 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissions.html +++ b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.html @@ -17,35 +17,36 @@ limitations under the License. + -Committed Submissions +Get By Timestamp + href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css"> + href="app/fusion/external/b2b/css/b2b-angular/font_icons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css"> + href="app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css"> + href="app/fusion/external/angular-gridster/dist/angular-gridster.min.css"> + href="static/fusion/sample/css/scribble.css" /> + href="static/fusion/sample/css/welcome.css" /> + href="app/fusion/styles/ecomp.css"> @@ -56,20 +57,19 @@ limitations under the License. + src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"> + src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"> + src="app/fusion/external/angular-gridster/dist/angular-gridster.min.js"> - - - + + + @@ -83,63 +83,62 @@ limitations under the License. - - + + - -
- -
- + + +
+ +
+ + \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.js b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.js new file mode 100644 index 0000000..623cf62 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestamp.js @@ -0,0 +1,19 @@ +/* + * 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. + */ + +var appDS2 = angular.module("GetByTimestamp", [ 'ngRoute', 'ngMessages', + 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', + 'ui.bootstrap.modal', 'App.Services', 'App.Config' ]); diff --git a/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampController.js b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampController.js new file mode 100644 index 0000000..cb75d5c --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampController.js @@ -0,0 +1,86 @@ +/* + * 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. + */ + +var app = angular.module('GetByTimestamp'); +app.controller('GetByTimestampController', + +function($scope, restAPISvc, $window, appContext) { + initialize(); + + function initialize() { + $scope.loadingLabs = true; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + restAPISvc.getRestAPI("/api/v1/results/getlabs/", function(data) { + $scope.labs = data; + $scope.loadingLabs = false; + }); + } + + $scope.selectedLabChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = true; + $scope.loadingVersions = false; + $scope.blueprints = []; + $scope.versions = []; + $scope.selectedBlueprint = {}; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintnamesoflab/" + + $scope.selectedLab, function(data) { + $scope.blueprints = data; + $scope.loadingBlueprints = false; + }); + } + + $scope.selectedBlueprintChange = function() { + if (!$scope.selectedLab) { + return; + } + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = true; + $scope.versions = []; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintversions/" + + $scope.selectedBlueprint + "/" + $scope.selectedLab, + function(data) { + $scope.versions = data; + $scope.loadingVersions = false; + }); + } + + $scope.selectedVersionChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + } + + $scope.get = function() { + if (!$scope.selectedLab || !$scope.selectedBlueprint + || !$scope.selectedVersion || !$scope.definedTimestamp) { + confirm("You must specify all data fields"); + return; + } + + $window.location.href = appContext + + "/validationresults#?blueprintName=" + + $scope.selectedBlueprint + "&" + "version=" + + $scope.selectedVersion + "&" + "lab=" + $scope.selectedLab + + "&" + "timestamp=" + $scope.definedTimestamp; + } + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampTemplate.html b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampTemplate.html new file mode 100644 index 0000000..0972b68 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/GetByTimestampTemplate.html @@ -0,0 +1,67 @@ + + +
+ +

Get Results By Timestamp

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/Route.js b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/Route.js similarity index 80% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/Route.js rename to ui/src/main/webapp/app/BluvalUI/GetByTimestamp/Route.js index 6f95fcc..b8fa594 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/Route.js +++ b/ui/src/main/webapp/app/BluvalUI/GetByTimestamp/Route.js @@ -17,9 +17,8 @@ appDS2 .config(function($routeProvider) { $routeProvider - .otherwise({ - templateUrl : 'app/AECBlueprintValidationUI/NewSubmission/NewSubmissionTemplate.html', - controller : "AECNewSubmissionController" + templateUrl : 'app/BluvalUI/GetByTimestamp/GetByTimestampTemplate.html', + controller : "GetByTimestampController" }); }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmission.html b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.html similarity index 58% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmission.html rename to ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.html index e551449..c9276d1 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/NewSubmission.html +++ b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.html @@ -17,35 +17,36 @@ limitations under the License. + -New Submission +Get Last Run + href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css"> + href="app/fusion/external/b2b/css/b2b-angular/font_icons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css"> + href="app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css"> + href="app/fusion/external/angular-gridster/dist/angular-gridster.min.css"> + href="static/fusion/sample/css/scribble.css" /> + href="static/fusion/sample/css/welcome.css" /> + href="app/fusion/styles/ecomp.css"> @@ -56,20 +57,19 @@ limitations under the License. + src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"> + src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"> + src="app/fusion/external/angular-gridster/dist/angular-gridster.min.js"> - - - + + + @@ -83,63 +83,62 @@ limitations under the License. - - + + - -
- -
- + + +
+ +
+ + \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmission.js b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.js similarity index 84% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmission.js rename to ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.js index 6d094b3..bbdcd4b 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmission.js +++ b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRun.js @@ -14,6 +14,6 @@ * limitations under the License. */ -var appDS2 = angular.module("AECNewSubmission", [ 'ngRoute', 'ngMessages', +var appDS2 = angular.module("GetLastRun", [ 'ngRoute', 'ngMessages', 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', - 'ui.bootstrap.modal', 'App.Services' ]); \ No newline at end of file + 'ui.bootstrap.modal', 'App.Services', 'App.Config' ]); diff --git a/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunController.js b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunController.js new file mode 100644 index 0000000..65f727e --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunController.js @@ -0,0 +1,149 @@ +/* + * 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. + */ + +var app = angular.module('GetLastRun'); +app.controller('GetLastRunController', + +function($scope, restAPISvc, $window, appContext) { + initialize(); + + function initialize() { + $scope.loadingLabs = true; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + restAPISvc.getRestAPI("/api/v1/results/getlabs/", function(data) { + $scope.labs = data; + $scope.loadingLabs = false; + }); + } + + $scope.selectedLabChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = true; + $scope.loadingVersions = false; + $scope.blueprints = []; + $scope.versions = []; + $scope.layers = []; + $scope.optionals = []; + $scope.outcomes = []; + $scope.selectedBlueprint = {}; + $scope.selectedVersion = {}; + $scope.selectedLayer = {}; + $scope.selectedOptional = {}; + $scope.selectedOutcome = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintnamesoflab/" + + $scope.selectedLab, function(data) { + $scope.blueprints = data; + $scope.loadingBlueprints = false; + }); + } + + $scope.selectedBlueprintChange = function() { + if (!$scope.selectedLab) { + return; + } + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = true; + $scope.versions = []; + $scope.layers = []; + $scope.optionals = []; + $scope.outcomes = []; + $scope.selectedVersion = {}; + $scope.selectedLayer = {}; + $scope.selectedOptional = {}; + $scope.selectedOutcome = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintversions/" + + $scope.selectedBlueprint + "/" + $scope.selectedLab, + function(data) { + $scope.versions = data; + $scope.loadingVersions = false; + }); + } + + $scope.selectedVersionChange = function() { + $scope.layers = []; + $scope.optionals = []; + $scope.outcomes = []; + $scope.selectedLayer = {}; + $scope.selectedOptional = {}; + $scope.selectedOutcome = {}; + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + $scope.layers = [ 'all', 'hardware', 'os', 'k8s', 'openstack' ]; + } + + $scope.selectedLayerChange = function() { + $scope.optionals = []; + $scope.outcomes = []; + $scope.selectedOptional = {}; + $scope.selectedOutcome = {}; + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + $scope.optionals = [ 'true', 'false' ]; + } + + $scope.selectedOptionalChange = function() { + $scope.outcomes = []; + $scope.selectedOutcome = {}; + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + $scope.outcomes = [ 'SUCCESS', 'FAILURE' ]; + } + + $scope.selectedOutcomeChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + } + + $scope.get = function() { + if (!$scope.selectedLab || !$scope.selectedBlueprint + || !$scope.selectedVersion || !$scope.selectedLayer + || !$scope.selectedOptional || !$scope.selectedOutcome) { + confirm("You must specify all data fields"); + return; + } + var outcome = ""; + if ($scope.selectedOutcome === 'SUCCESS') { + outcome = true; + } else { + outcome = false; + } + var allLayers = ""; + var layer = ""; + if ($scope.selectedLayer === 'all') { + allLayers = "true"; + } else { + layer = $scope.selectedLayer; + } + $window.location.href = appContext + + "/validationresults#?blueprintName=" + + $scope.selectedBlueprint + "&" + "version=" + + $scope.selectedVersion + "&" + "lab=" + $scope.selectedLab + + "&" + "allLayers=" + allLayers + "&" + "layer=" + layer + "&" + + "optional=" + $scope.selectedOptional + "&" + "outcome=" + + outcome; + } + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunTemplate.html b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunTemplate.html new file mode 100644 index 0000000..3e0dee5 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetLastRun/GetLastRunTemplate.html @@ -0,0 +1,93 @@ + + +
+ +

Get Last Run

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/Route.js b/ui/src/main/webapp/app/BluvalUI/GetLastRun/Route.js similarity index 78% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/Route.js rename to ui/src/main/webapp/app/BluvalUI/GetLastRun/Route.js index 48a9a5a..4885d07 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/CommittedSubmissions/Route.js +++ b/ui/src/main/webapp/app/BluvalUI/GetLastRun/Route.js @@ -18,7 +18,7 @@ appDS2 .config(function($routeProvider) { $routeProvider .otherwise({ - templateUrl : 'app/AECBlueprintValidationUI/CommittedSubmissions/CommittedSubmissionsTemplate.html', - controller : "AECCommittedSubmissionsController" + templateUrl : 'app/BluvalUI/GetLastRun/GetLastRunTemplate.html', + controller : "GetLastRunController" }); }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionId.html b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.html similarity index 58% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionId.html rename to ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.html index 437c42f..2439c20 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/GetBySubmissionId/GetBySubmissionId.html +++ b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.html @@ -17,35 +17,36 @@ limitations under the License. + -Get By Submission Id +Get Most Recent Results + href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css"> + href="app/fusion/external/b2b/css/b2b-angular/font_icons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css"> + href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css"> + href="app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css"> + href="app/fusion/external/angular-gridster/dist/angular-gridster.min.css"> + href="static/fusion/sample/css/scribble.css" /> + href="static/fusion/sample/css/welcome.css" /> + href="app/fusion/styles/ecomp.css"> @@ -56,20 +57,19 @@ limitations under the License. + src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"> + src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"> + src="app/fusion/external/angular-gridster/dist/angular-gridster.min.js"> - - - + + + @@ -83,63 +83,62 @@ limitations under the License. - - + + - -
- -
- + + +
+ +
+ + \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.js b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.js new file mode 100644 index 0000000..8fbbc64 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecent.js @@ -0,0 +1,20 @@ +/* + * 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. + */ + +var appDS2 = angular.module("GetMostRecent", ['ngRoute', 'ngMessages', + 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', + 'ui.bootstrap.modal', 'App.Services', 'App.Config']); + diff --git a/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentController.js b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentController.js new file mode 100644 index 0000000..76307eb --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentController.js @@ -0,0 +1,82 @@ +/* + * 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. + */ + +var app = angular.module('GetMostRecent'); +app.controller('GetMostRecentController', function($scope, restAPISvc, $window, + appContext) { + + initialize(); + + function initialize() { + + $scope.loadingLabs = true; + $scope.loadingBlueprints = false; + $scope.loadingVersions = false; + $scope.loadingResults = false; + restAPISvc.getRestAPI("/api/v1/results/getlabs/", function(data) { + $scope.labs = data; + $scope.loadingLabs = false; + }); + } + + $scope.selectedLabChange = function() { + $scope.loadingLabs = false; + $scope.loadingBlueprints = true; + $scope.loadingVersions = false; + $scope.blueprints = []; + $scope.versions = []; + $scope.selectedBlueprint = {}; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintnamesoflab/" + + $scope.selectedLab, function(data) { + $scope.blueprints = data; + $scope.loadingBlueprints = false; + }); + } + + $scope.selectedBlueprintChange = function() { + if (!$scope.selectedLab) { + return; + } + $scope.loadingLabs = false; + $scope.loadingBlueprints = false; + $scope.loadingVersions = true; + $scope.versions = []; + $scope.selectedVersion = {}; + restAPISvc.getRestAPI("/api/v1/results/getblueprintversions/" + + $scope.selectedBlueprint + "/" + $scope.selectedLab, + function(data) { + $scope.versions = data; + $scope.loadingVersions = false; + }); + } + + $scope.selectedVersionChange = function() { + } + + $scope.get = function() { + if (!$scope.selectedLab || !$scope.selectedBlueprint + || !$scope.selectedVersion) { + confirm("You must specify all data fields"); + return; + } + $window.location.href = appContext + "/validationresults#?lab=" + + $scope.selectedLab + "&" + "blueprintName=" + + $scope.selectedBlueprint + "&" + "version=" + + $scope.selectedVersion; + } + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentTemplate.html b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentTemplate.html new file mode 100644 index 0000000..6985bd8 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/GetMostRecentTemplate.html @@ -0,0 +1,65 @@ + +
+ +

Get Most Recent Blueprint Validation + Results

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/GetMostRecent/Route.js b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/Route.js new file mode 100644 index 0000000..951eafc --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/GetMostRecent/Route.js @@ -0,0 +1,22 @@ +/* + * 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. + */ + +appDS2.config(function($routeProvider) { + $routeProvider.otherwise({ + templateUrl : 'app/BluvalUI/GetMostRecent/GetMostRecentTemplate.html', + controller : "GetMostRecentController" + }); +}); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.html b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.html new file mode 100644 index 0000000..430e4de --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.html @@ -0,0 +1,165 @@ + + + + + + + + + + + New Submission + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.js b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.js new file mode 100644 index 0000000..e46c86a --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmission.js @@ -0,0 +1,19 @@ +/* + * 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. + */ + +var appDS2 = angular.module("NewSubmission", ['ngRoute', 'ngMessages', + 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', + 'ui.bootstrap.modal', 'App.Services']); \ No newline at end of file diff --git a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionController.js similarity index 74% rename from ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js rename to ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionController.js index 2135680..1f65975 100644 --- a/ui/src/main/webapp/app/AECBlueprintValidationUI/NewSubmission/AECNewSubmissionController.js +++ b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionController.js @@ -14,10 +14,10 @@ * limitations under the License. */ -var app = angular.module('AECNewSubmission'); +var app = angular.module('NewSubmission'); app .controller( - 'AECNewSubmissionController', + 'NewSubmissionController', function($scope, restAPISvc) { initialize(); @@ -25,7 +25,7 @@ app function initialize() { restAPISvc .getRestAPI( - "/api/blueprintInstanceForValidation/", + "/api/v1/blueprintinstanceforvalidation/", function(data) { $scope.blueprintInstancesForValidation = data; $scope.blueprintNames = []; @@ -41,12 +41,12 @@ app } }); }); - restAPISvc.getRestAPI("/api/timeslots/", - function(data) { - $scope.timeslots = data; - $scope.declerativeTimeslots = []; - angular.forEach($scope.timeslots, function( - timeslot) { + restAPISvc.getRestAPI("/api/v1/timeslots/", function( + data) { + $scope.timeslots = data; + $scope.declerativeTimeslots = []; + angular.forEach($scope.timeslots, + function(timeslot) { var temp = "id: " + timeslot.timeslotId + " Start date and time: " + timeslot.startDateTime @@ -57,11 +57,15 @@ app + " lab :" + timeslot.lab.lab; $scope.declerativeTimeslots.push(temp); }); - }); + }); } $scope.selectedBluePrintNameChange = function() { $scope.blueprintVersions = []; $scope.blueprintLayers = []; + $scope.optionals = []; + $scope.selectedBlueprintVersion = {}; + $scope.selectedBlueprintLayer = {}; + $scope.selectedOptional = ""; angular .forEach( $scope.blueprintInstancesForValidation, @@ -76,7 +80,13 @@ app }); } $scope.selectedBluePrintVersionChange = function() { + if (!$scope.selectedBlueprintName) { + return; + } $scope.blueprintLayers = []; + $scope.optionals = []; + $scope.selectedBlueprintLayer = {}; + $scope.selectedOptional = ""; angular .forEach( $scope.blueprintInstancesForValidation, @@ -91,30 +101,23 @@ app } } }); + $scope.blueprintLayers.push("all"); + } + + $scope.selectedBluePrintLayerChange = function() { + $scope.optionals = [ 'true', 'false' ]; } $scope.submit = function() { if (!$scope.selectedBlueprintName || !$scope.selectedBlueprintVersion || !$scope.selectedBlueprintLayer + || !$scope.selectedOptional || !$scope.selectedDeclerativeTimeslot) { confirm("You must specify all data fields"); return; } - var finalBlueprint; var finalTimeslot; - angular - .forEach( - $scope.blueprintInstancesForValidation, - function(blueprintInstance) { - if (blueprintInstance["blueprint"]["blueprintName"] === $scope.selectedBlueprintName) { - if (blueprintInstance["version"] === $scope.selectedBlueprintVersion) { - if (blueprintInstance["layer"] === $scope.selectedBlueprintLayer) { - finalBlueprint = blueprintInstance; - } - } - } - }); var selectedDeclerativeTimeslotId = $scope.selectedDeclerativeTimeslot .substring( $scope.selectedDeclerativeTimeslot @@ -131,17 +134,35 @@ app finalTimeslot = timeslot; } }); - var submission = { - "blueprintInstanceForValidation" : finalBlueprint, + var allLayers = "false"; + if ($scope.selectedBlueprintLayer === 'all') { + allLayers = "true"; + } + var wRobotTestResults = []; + if (allLayers === "false") { + wRobotTestResults = [ { + "blueprintLayer" : $scope.selectedBlueprintLayer + } ]; + } + + var validationNexusTestResult = { + "blueprintName" : $scope.selectedBlueprintName, + "version" : $scope.selectedBlueprintVersion, + "allLayers" : allLayers, + "wRobotNexusTestResults" : wRobotTestResults, + "optional" : $scope.selectedOptional + }; + var submissionData = { + "validationNexusTestResult" : validationNexusTestResult, "timeslot" : finalTimeslot }; restAPISvc .postRestAPI( - "/api/submission/", - submission, + "/api/v1/submission/", + submissionData, function(data) { if (data !== undefined) { - var confirmText = "The blueprint instance for validation has been submitted successfully. Submissionn id:" + var confirmText = "The blueprint instance for validation has been submitted successfully. Submission id:" + data.submissionId; confirm(confirmText); } else { @@ -151,6 +172,7 @@ app $scope.selectedBlueprintName = {}; $scope.selectedBlueprintVersion = {}; $scope.selectedBlueprintLayer = {}; + $scope.selectedOptional = ""; $scope.selectedDeclerativeTimeslot = {}; } diff --git a/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionTemplate.html b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionTemplate.html new file mode 100644 index 0000000..049c8bc --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/NewSubmission/NewSubmissionTemplate.html @@ -0,0 +1,85 @@ + + +
+
+

New Submission

+

Submission form

+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ + +
+
+ +
+
+
+ +
+ +
+
+
diff --git a/ui/src/main/webapp/app/BluvalUI/NewSubmission/Route.js b/ui/src/main/webapp/app/BluvalUI/NewSubmission/Route.js new file mode 100644 index 0000000..a9c8484 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/NewSubmission/Route.js @@ -0,0 +1,24 @@ +/* + * 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. + */ + +appDS2 + .config(function ($routeProvider) { + $routeProvider + .otherwise({ + templateUrl: 'app/BluvalUI/NewSubmission/NewSubmissionTemplate.html', + controller: "NewSubmissionController" + }); + }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/Route.js b/ui/src/main/webapp/app/BluvalUI/ValidationResults/Route.js new file mode 100644 index 0000000..57845b4 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/Route.js @@ -0,0 +1,24 @@ +/* + * 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. + */ + +appDS2 + .config(function($routeProvider) { + $routeProvider + .otherwise({ + templateUrl : 'app/BluvalUI/ValidationResults/ValidationResultsTemplate.html', + controller : "ValidationResultsController" + }); + }); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsController.js b/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsController.js new file mode 100644 index 0000000..8804de8 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsController.js @@ -0,0 +1,85 @@ +/* + * 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. + */ + +var app = angular.module('ValidationResults'); +app.controller('TestSuiteResultsController', function($scope, + generalValidationResultsSvc) { + + initialize(); + + function initialize() { + $scope.showTestSuitesResults = false; + $scope.wRobotTestResults = []; + $scope.selectedTestId = null; + $scope.selectedTest = null; + $scope.resultsLayers = []; + $scope.resultsLayerTestSuitesNames = []; + $scope.selectedRobotTestResult = []; + $scope.selectedLayer = []; + $scope.selectedTestSuiteName = []; + + $scope.validationNexusTestResult = $scope.params; + $scope.wRobotTestResults = $scope.params.wRobotNexusTestResults; + if (generalValidationResultsSvc + .mapResult($scope.validationNexusTestResult) === null) { + confirm("No data was found"); + } else { + $scope.showTestSuitesResults = true; + angular.forEach($scope.wRobotTestResults, function(result) { + $scope.resultsLayers.push(result.blueprintLayer); + }); + } + + } + + $scope.selectedResultsLayerChange = function(selectedLayer) { + $scope.selectedTestId = null; + $scope.selectedTest = null; + $scope.resultsLayerTestSuitesNames = []; + $scope.robotTestResults = []; + $scope.selectedRobotTestResult = []; + $scope.selectedTestSuiteName = []; + var selectedLayerResult = []; + angular.forEach($scope.wRobotTestResults, function(result) { + if (result.blueprintLayer === selectedLayer) { + selectedLayerResult = result; + } + }); + $scope.robotTestResults = selectedLayerResult.robotTestResults; + angular.forEach($scope.robotTestResults, function(robotTestResult) { + $scope.resultsLayerTestSuitesNames.push(robotTestResult.name); + }); + } + + $scope.selectedTestSuitesNameChange = function(selectedTestSuiteName) { + if (!selectedTestSuiteName) { + return; + } + $scope.selectedTestId = null; + $scope.selectedTest = null; + angular.forEach($scope.robotTestResults, function(robotTestResult) { + if (robotTestResult.name.trim() === selectedTestSuiteName.trim()) { + $scope.selectedRobotTestResult = robotTestResult; + } + }); + } + + $scope.setClickedTest = function(test) { + $scope.selectedTestId = test.id; + $scope.selectedTest = test; + } + +}); diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsModal.html b/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsModal.html new file mode 100644 index 0000000..82eb5fe --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsModal.html @@ -0,0 +1,455 @@ + +
+ + + +
+

+

Display Test Suites Results

+ +

+
+

Select a blueprint layer:

+
+ +
+ +

Select a test suite of the + selected layer in order to be displayed:

+
+ +
+
+ +


+ +
+
+

+
+

+ General 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}} +
+
+
+
+
+
+ +

+
+

+ 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

    +
  • +
+
+ +

+
+

Test Cases

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

+
+

 Full Name 

+
+

Documentation 

+
+

Status 

+
+

Start Time 

+
+

End Time 

+
+

Critical 

+
+

Message 

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

+
+
    +

    Robot keywords of + the selected test case

    +
  • +
+
+ +
+
+ + + + +
+
\ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.Services.js b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.Services.js new file mode 100644 index 0000000..bfda0b1 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.Services.js @@ -0,0 +1,101 @@ +/* + * 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. + */ + +var app = angular.module('ValidationResults'); + +app.factory('generalValidationResultsSvc', [ function() { + var svc = []; + svc.getBlueprintLayers = function(wRobotNexusTestResults) { + var layers = []; + angular.forEach(wRobotNexusTestResults, + function(wRobotNexusTestResult) { + if (wRobotNexusTestResult.blueprintLayer !== undefined) { + layers.push(wRobotNexusTestResult.blueprintLayer); + } + }); + return layers; + }; + svc.mapResult = function(validationNexusTestResult) { + if (!validationNexusTestResult.timestamp) { + return null; + } + if (!validationNexusTestResult.wRobotNexusTestResults) { + return null; + } + if (validationNexusTestResult.wRobotNexusTestResults.length === 0) { + return null; + } + var resultExistence = false; + angular.forEach(validationNexusTestResult.wRobotNexusTestResults, + function(result) { + if (result.robotTestResults + && result.robotTestResults.length > 0) { + resultExistence = true; + } + }); + if (resultExistence) { + if (validationNexusTestResult.result === true) { + return 'SUCCESS'; + } + return 'FAILURE' + } + return null; + }; + svc.filterWithLayer = function(validationNexusTestResults, filterLayer) { + if (filterLayer === undefined || filterLayer === '') { + return validationNexusTestResults; + } + var filteredResults = []; + angular.forEach(validationNexusTestResults, function( + validationNexusTestResult) { + angular.forEach(validationNexusTestResult.wRobotNexusTestResults, + function(wRobotNexusTestResult) { + if (wRobotNexusTestResult.blueprintLayer.toLowerCase() + .includes(filterLayer.toLowerCase())) { + filteredResults.push(validationNexusTestResult); + } + }); + }); + return filteredResults; + } + svc.filterWithResult = function(validationNexusTestResults, filterResult) { + if (filterResult === undefined || filterResult === '') { + return validationNexusTestResults; + } + var filteredResults = []; + angular.forEach(validationNexusTestResults, function( + validationNexusTestResult) { + if (validationNexusTestResult.result === true + && 'success'.includes(filterResult.toLowerCase())) { + filteredResults.push(validationNexusTestResult); + } else if (validationNexusTestResult.result === false + && 'failure'.includes(filterResult.toLowerCase())) { + filteredResults.push(validationNexusTestResult); + } + }); + return filteredResults; + } + svc.getLab = function(silo, silos) { + var lab = null; + angular.forEach(silos, function(siloData) { + if (silo === siloData.silo) { + lab = siloData.lab.lab; + } + }); + return lab; + } + return svc; +} ]); \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.html b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.html new file mode 100644 index 0000000..7015b76 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.html @@ -0,0 +1,183 @@ + + + + + + + + + + +Get Validation Results + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.js b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.js new file mode 100644 index 0000000..d071e9e --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResults.js @@ -0,0 +1,20 @@ +/* + * 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. + */ + +var appDS2 = angular.module("ValidationResults", ['ngRoute', 'ngMessages', + 'modalServices', 'ngCookies', 'b2b.att', 'gridster', 'ui.bootstrap', + 'ui.bootstrap.modal', 'App.Services', 'App.Config']); + diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsController.js b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsController.js new file mode 100644 index 0000000..c4e9e72 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsController.js @@ -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. + */ + +var app = angular.module('ValidationResults'); +app + .controller( + 'ValidationResultsController', + function($scope, restAPISvc, generalValidationResultsSvc, + $window, appContext, $location, $modal, $rootScope) { + + $scope.getBlueprintLayers = generalValidationResultsSvc.getBlueprintLayers; + $scope.mapResult = generalValidationResultsSvc.mapResult; + $scope.filterWithLayer = generalValidationResultsSvc.filterWithLayer; + $scope.filterWithResult = generalValidationResultsSvc.filterWithResult; + $scope.getLab = generalValidationResultsSvc.getLab; + + initialize(); + + function initialize() { + $scope.loadingResults = true; + $scope.validationNexusTestResults = []; + $scope.silos = []; + var searchObject = $location.search(); + var submissionId = searchObject.submissionId; + var blueprintName = searchObject.blueprintName; + var version = searchObject.version; + var lab = searchObject.lab; + var allLayers = searchObject.allLayers; + var layer = searchObject.layer; + var optional = searchObject.optional; + var outcome = searchObject.outcome; + var timestamp = searchObject.timestamp; + var date = searchObject.date; + var reqUrl = ""; + if (submissionId) { + reqUrl = "/api/v1/results/getbysubmissionid/" + + submissionId; + } else if (outcome !== undefined && !layer) { + reqUrl = "/api/v1/results/getlastrun/" + lab + "/" + + blueprintName + "/" + version + "/" + + allLayers + "/" + optional + "/" + + outcome; + } else if (outcome !== undefined) { + var layers = []; + layers.push(layer); + reqUrl = "/api/v1/results/getlastrunoflayers/" + + lab + "/" + blueprintName + "/" + version + + "/" + layers + "/" + optional + "/" + + outcome; + } else if (timestamp) { + reqUrl = "/api/v1/results/getbytimestamp/" + lab + + "/" + blueprintName + "/" + version + "/" + + timestamp; + } else if (date) { + reqUrl = "/api/v1/results/getbasedondate/" + lab + + "/" + blueprintName + "/" + version + "/" + + date; + } else { + reqUrl = "/api/v1/results/getmostrecent/" + + blueprintName + "/" + version + "/" + lab; + } + restAPISvc + .getRestAPI( + reqUrl, + function(resultData) { + if (resultData) { + restAPISvc + .getRestAPI( + "/api/v1/silo/", + function( + siloData) { + $scope.silos = siloData; + $scope.loadingResults = false; + if (!Array + .isArray(resultData)) { + $scope.validationNexusTestResults + .push(resultData); + } else { + $scope.validationNexusTestResults = resultData; + } + }); + } else { + confirm("No data was found"); + $scope.loadingResults = false; + } + }); + $scope.descending = true; + } + + $scope.dateTimeSort = function(validationNexusTestResult) { + return new Date(validationNexusTestResult.dateOfStorage) + .getTime(); + } + + $scope.descendingOrder = function() { + $scope.descending = true; + } + + $scope.ascendingOrder = function() { + $scope.descending = false; + } + + $scope.refreshValidationResults = function() { + initialize(); + } + + $scope.getTestSuiteResults = function( + validationNexusTestResult) { + if (!generalValidationResultsSvc + .mapResult(validationNexusTestResult)) { + return; + } + var scope = $rootScope.$new(); + scope.params = validationNexusTestResult; + $modal + .open({ + scope : scope, + templateUrl : 'app/BluvalUI/ValidationResults/TestSuiteResults/TestSuiteResultsModal.html', + controller : 'TestSuiteResultsController' + }); + } + + }); diff --git a/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsTemplate.html b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsTemplate.html new file mode 100644 index 0000000..a327ca0 --- /dev/null +++ b/ui/src/main/webapp/app/BluvalUI/ValidationResults/ValidationResultsTemplate.html @@ -0,0 +1,239 @@ + +
+ + + +

Blueprint Validation Results

+ +
+ +
+ +

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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Lab Blueprint VersionTimestamp  +

Date/Time of result

+

+ storage  +

+
Optional test cases All layers Layer(s) Submission Id Result 
+ {{ getLab(validationNexusTestResult.silo, silos) + }}{{ + validationNexusTestResult.blueprintName }}{{ + validationNexusTestResult.version }}{{ + validationNexusTestResult.timestamp }}{{ + validationNexusTestResult.dateOfStorage }}{{ + validationNexusTestResult.optional }}{{ + validationNexusTestResult.allLayers }} +
+ {{layer}}
+
{{ + validationNexusTestResult.submissionId }} + + +
+ +
+ +
\ No newline at end of file diff --git a/ui/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html b/ui/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html index 0d85329..05ee699 100644 --- a/ui/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html +++ b/ui/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html @@ -16,13 +16,14 @@ limitations under the License. + - - - -Page Redirection + + + + Page Redirection + \ No newline at end of file