diff options
80 files changed, 1554 insertions, 157 deletions
diff --git a/jjb/apex/apex.yml b/jjb/apex/apex.yml index 3e78f32c9..60340e9ca 100644 --- a/jjb/apex/apex.yml +++ b/jjb/apex/apex.yml @@ -52,6 +52,7 @@ - 'os-odl_l3-fdio_dvr-noha' - 'os-odl_l3-fdio_dvr-ha' - 'os-odl_l3-csit-noha' + - 'os-odl_l3-nofeature-noha' - 'os-onos-nofeature-ha' - 'gate' diff --git a/jjb/armband/armband-ci-jobs.yml b/jjb/armband/armband-ci-jobs.yml index 667871726..ddcbbd038 100644 --- a/jjb/armband/armband-ci-jobs.yml +++ b/jjb/armband/armband-ci-jobs.yml @@ -56,6 +56,10 @@ slave-label: arm-pod3 installer: fuel <<: *danube + - arm-pod3-2: + slave-label: arm-pod3-2 + installer: fuel + <<: *danube #-------------------------------- # master #-------------------------------- @@ -67,6 +71,10 @@ slave-label: arm-pod3 installer: fuel <<: *master + - arm-pod3-2: + slave-label: arm-pod3-2 + installer: fuel + <<: *master #-------------------------------- # scenarios #-------------------------------- @@ -262,23 +270,23 @@ - trigger: name: 'fuel-os-odl_l2-nofeature-ha-armband-baremetal-master-trigger' triggers: - - timed: '0 8 * * 1,3,5,7' + - timed: '0 0 * * 1' - trigger: name: 'fuel-os-nosdn-nofeature-ha-armband-baremetal-master-trigger' triggers: - - timed: '0 16 * * 2,7' + - timed: '0 0 * * 2' - trigger: name: 'fuel-os-odl_l3-nofeature-ha-armband-baremetal-master-trigger' triggers: - - timed: '0 16 * * 1,4,6' + - timed: '0 0 * * 3' - trigger: name: 'fuel-os-odl_l2-bgpvpn-ha-armband-baremetal-master-trigger' triggers: - - timed: '0 8 * * 2,4,6' + - timed: '0 0 * * 4' - trigger: name: 'fuel-os-odl_l2-nofeature-noha-armband-baremetal-master-trigger' triggers: - - timed: '0 16 * * 3,5' + - timed: '0 0 * * 5' - trigger: name: 'fuel-os-odl_l2-sfc-ha-armband-baremetal-master-trigger' triggers: @@ -294,31 +302,31 @@ - trigger: name: 'fuel-os-odl_l2-nofeature-ha-armband-baremetal-danube-trigger' triggers: - - timed: '0 0 * * 1' + - timed: '0 8 * * 1,4' - trigger: name: 'fuel-os-nosdn-nofeature-ha-armband-baremetal-danube-trigger' triggers: - - timed: '0 0 * * 2' + - timed: '0 16 * * 1,4' - trigger: name: 'fuel-os-odl_l2-bgpvpn-ha-armband-baremetal-danube-trigger' triggers: - - timed: '0 0 * * 4' + - timed: '0 8 * * 2,5' - trigger: name: 'fuel-os-odl_l3-nofeature-ha-armband-baremetal-danube-trigger' triggers: - - timed: '0 0 * * 3' + - timed: '0 16 * * 2,5' - trigger: name: 'fuel-os-odl_l2-nofeature-noha-armband-baremetal-danube-trigger' triggers: - - timed: '0 0 * * 5' + - timed: '0 8 * * 3,6' - trigger: name: 'fuel-os-odl_l2-sfc-ha-armband-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 16 * * 3,6' - trigger: name: 'fuel-os-odl_l2-sfc-noha-armband-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 8,16 * * 7' #--------------------------------------------------------------- # Enea Armband CI Virtual Triggers running against master branch #--------------------------------------------------------------- @@ -505,3 +513,65 @@ name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-danube-trigger' triggers: - timed: '' +#-------------------------------------------------------------------------- +# Enea Armband POD 3 Triggers running against master branch (aarch64 slave) +#-------------------------------------------------------------------------- +- trigger: + name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +#-------------------------------------------------------------------------- +# Enea Armband POD 3 Triggers running against danube branch (aarch64 slave) +#-------------------------------------------------------------------------- +- trigger: + name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' diff --git a/jjb/armband/armband-deploy.sh b/jjb/armband/armband-deploy.sh index adabfcaeb..2e5aa3924 100755 --- a/jjb/armband/armband-deploy.sh +++ b/jjb/armband/armband-deploy.sh @@ -32,6 +32,14 @@ fi # set deployment parameters export TMPDIR=${WORKSPACE}/tmpdir + +# arm-pod3-2 is an aarch64 jenkins slave for the same POD as the +# x86 jenkins slave arm-pod3; therefore we use the same pod name +# to deploy the pod from both jenkins slaves +if [[ "${NODE_NAME}" == "arm-pod3-2" ]]; then + NODE_NAME="arm-pod3" +fi + LAB_NAME=${NODE_NAME/-*} POD_NAME=${NODE_NAME/*-} diff --git a/jjb/armband/armband-verify-jobs.yml b/jjb/armband/armband-verify-jobs.yml index 3486718e4..567456d9b 100644 --- a/jjb/armband/armband-verify-jobs.yml +++ b/jjb/armband/armband-verify-jobs.yml @@ -86,6 +86,7 @@ pattern: 'ci/**' - compare-type: ANT pattern: 'patches/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/availability/availability.yml b/jjb/availability/availability.yml index 9cb7f8899..302bbc996 100644 --- a/jjb/availability/availability.yml +++ b/jjb/availability/availability.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/barometer/barometer.yml b/jjb/barometer/barometer.yml index 8c0f6ce53..9ec30e809 100644 --- a/jjb/barometer/barometer.yml +++ b/jjb/barometer/barometer.yml @@ -55,6 +55,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' @@ -105,6 +106,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/compass4nfv/compass-ci-jobs.yml b/jjb/compass4nfv/compass-ci-jobs.yml index c934d1985..237f8944d 100644 --- a/jjb/compass4nfv/compass-ci-jobs.yml +++ b/jjb/compass4nfv/compass-ci-jobs.yml @@ -32,11 +32,11 @@ <<: *master - baremetal: slave-label: compass-baremetal - os-version: 'trusty' + os-version: 'xenial' <<: *danube - virtual: slave-label: compass-virtual - os-version: 'trusty' + os-version: 'xenial' <<: *danube #-------------------------------- # master @@ -323,27 +323,27 @@ - trigger: name: 'compass-os-nosdn-nofeature-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 9 * * *' - trigger: name: 'compass-os-nosdn-openo-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 13 * * *' - trigger: name: 'compass-os-odl_l2-nofeature-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 17 * * *' - trigger: name: 'compass-os-odl_l3-nofeature-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 21 * * *' - trigger: name: 'compass-os-onos-nofeature-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 1 * * *' - trigger: name: 'compass-os-ocl-nofeature-ha-baremetal-danube-trigger' triggers: - - timed: '' + - timed: '0 5 * * *' - trigger: name: 'compass-os-onos-sfc-ha-baremetal-danube-trigger' triggers: diff --git a/jjb/compass4nfv/compass-verify-jobs.yml b/jjb/compass4nfv/compass-verify-jobs.yml index 7c9f87a31..e625c686a 100644 --- a/jjb/compass4nfv/compass-verify-jobs.yml +++ b/jjb/compass4nfv/compass-verify-jobs.yml @@ -96,6 +96,7 @@ file-paths: - compare-type: ANT pattern: '**/*' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/conductor/conductor.yml b/jjb/conductor/conductor.yml index 1d47624e1..d2ce649fc 100644 --- a/jjb/conductor/conductor.yml +++ b/jjb/conductor/conductor.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/copper/copper.yml b/jjb/copper/copper.yml index e380fd555..d06afe4c0 100644 --- a/jjb/copper/copper.yml +++ b/jjb/copper/copper.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/daisy4nfv/daisy4nfv-merge-jobs.yml b/jjb/daisy4nfv/daisy4nfv-merge-jobs.yml index a4489334a..11531f4a4 100644 --- a/jjb/daisy4nfv/daisy4nfv-merge-jobs.yml +++ b/jjb/daisy4nfv/daisy4nfv-merge-jobs.yml @@ -84,6 +84,7 @@ pattern: 'code/**' - compare-type: ANT pattern: 'deploy/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/daisy4nfv/daisy4nfv-verify-jobs.yml b/jjb/daisy4nfv/daisy4nfv-verify-jobs.yml index 18093f034..ee78ab59f 100644 --- a/jjb/daisy4nfv/daisy4nfv-verify-jobs.yml +++ b/jjb/daisy4nfv/daisy4nfv-verify-jobs.yml @@ -88,6 +88,7 @@ pattern: 'code/**' - compare-type: ANT pattern: 'deploy/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/domino/domino.yml b/jjb/domino/domino.yml index 5fd9db3f1..8c9be120b 100644 --- a/jjb/domino/domino.yml +++ b/jjb/domino/domino.yml @@ -49,6 +49,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/dpacc/dpacc.yml b/jjb/dpacc/dpacc.yml index bc61d7447..63eb044ad 100644 --- a/jjb/dpacc/dpacc.yml +++ b/jjb/dpacc/dpacc.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/escalator/escalator.yml b/jjb/escalator/escalator.yml index 2265dafce..041a41f91 100644 --- a/jjb/escalator/escalator.yml +++ b/jjb/escalator/escalator.yml @@ -73,6 +73,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' @@ -185,6 +186,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/fuel/fuel-project-jobs.yml b/jjb/fuel/fuel-project-jobs.yml index 80b9deb8f..1f0ddd363 100644 --- a/jjb/fuel/fuel-project-jobs.yml +++ b/jjb/fuel/fuel-project-jobs.yml @@ -125,6 +125,7 @@ pattern: 'build/**' - compare-type: ANT pattern: 'deploy/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' @@ -193,6 +194,7 @@ pattern: 'build/**' - compare-type: ANT pattern: 'deploy/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/fuel/fuel-verify-jobs.yml b/jjb/fuel/fuel-verify-jobs.yml index a4bd6aa36..549f7dafa 100644 --- a/jjb/fuel/fuel-verify-jobs.yml +++ b/jjb/fuel/fuel-verify-jobs.yml @@ -88,6 +88,7 @@ pattern: 'build/**' - compare-type: ANT pattern: 'deploy/**' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/functest/functest-daily-jobs.yml b/jjb/functest/functest-daily-jobs.yml index 972c4fd2f..a3268d3e5 100644 --- a/jjb/functest/functest-daily-jobs.yml +++ b/jjb/functest/functest-daily-jobs.yml @@ -158,6 +158,10 @@ slave-label: '{pod}' installer: fuel <<: *master + - arm-pod3-2: + slave-label: '{pod}' + installer: fuel + <<: *master - zte-pod1: slave-label: '{pod}' installer: fuel @@ -186,6 +190,10 @@ slave-label: '{pod}' installer: fuel <<: *danube + - arm-pod3-2: + slave-label: '{pod}' + installer: fuel + <<: *danube # PODs for verify jobs triggered by each patch upload - ool-virtual1: slave-label: '{pod}' diff --git a/jjb/functest/functest-project-jobs.yml b/jjb/functest/functest-project-jobs.yml index 42c19a777..14ad73a91 100644 --- a/jjb/functest/functest-project-jobs.yml +++ b/jjb/functest/functest-project-jobs.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/global/slave-params.yml b/jjb/global/slave-params.yml index 6aa2e717c..1905a098a 100644 --- a/jjb/global/slave-params.yml +++ b/jjb/global/slave-params.yml @@ -747,6 +747,24 @@ default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab description: 'Base URI to the configuration directory' - parameter: + name: 'arm-pod3-2-defaults' + parameters: + - node: + name: SLAVE_NAME + description: 'Slave name on Jenkins' + allowed-slaves: + - arm-pod3-2 + default-slaves: + - arm-pod3-2 + - string: + name: GIT_BASE + default: https://gerrit.opnfv.org/gerrit/$PROJECT + description: 'Git URL to use on this Jenkins Slave' + - string: + name: LAB_CONFIG_URL + default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab + description: 'Base URI to the configuration directory' +- parameter: name: 'intel-virtual6-defaults' parameters: - node: diff --git a/jjb/infra/bifrost-cleanup-job.yml b/jjb/infra/bifrost-cleanup-job.yml index f1b38ca4b..571e275da 100644 --- a/jjb/infra/bifrost-cleanup-job.yml +++ b/jjb/infra/bifrost-cleanup-job.yml @@ -88,6 +88,7 @@ trigger-on: # We only run this when the change is merged or # abandoned since we don't need the logs anymore + - patchset-uploaded-event: 'false' - change-merged-event: 'true' - change-abandoned-event: 'true' - change-restored-event: 'false' @@ -102,11 +103,13 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'doc/**' - compare-type: ANT pattern: 'releasenotes/**' + disable-strict-forbidden-file-verification: 'true' readable-message: true - trigger: name: 'opnfv-gerrit-trigger-cleanup' @@ -116,6 +119,7 @@ trigger-on: # We only run this when the change is merged or # abandoned since we don't need the logs anymore + - patchset-uploaded-event: 'false' - change-merged-event: 'true' - change-abandoned-event: 'true' - change-restored-event: 'false' diff --git a/jjb/infra/bifrost-verify-jobs.yml b/jjb/infra/bifrost-verify-jobs.yml index d595d4bef..33032bc7b 100644 --- a/jjb/infra/bifrost-verify-jobs.yml +++ b/jjb/infra/bifrost-verify-jobs.yml @@ -172,11 +172,13 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'doc/**' - compare-type: ANT pattern: 'releasenotes/**' + disable-strict-forbidden-file-verification: 'true' readable-message: true - trigger: name: 'opnfv-gerrit-trigger' diff --git a/jjb/ipv6/ipv6.yml b/jjb/ipv6/ipv6.yml index a6745cd99..b0db7640a 100644 --- a/jjb/ipv6/ipv6.yml +++ b/jjb/ipv6/ipv6.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/joid/joid-verify-jobs.yml b/jjb/joid/joid-verify-jobs.yml index 7b8ce7701..03fab553e 100644 --- a/jjb/joid/joid-verify-jobs.yml +++ b/jjb/joid/joid-verify-jobs.yml @@ -86,6 +86,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/models/models.yml b/jjb/models/models.yml index 89d22bcbd..683103678 100644 --- a/jjb/models/models.yml +++ b/jjb/models/models.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/moon/moon.yml b/jjb/moon/moon.yml index a318bc54d..fb28feb53 100644 --- a/jjb/moon/moon.yml +++ b/jjb/moon/moon.yml @@ -42,6 +42,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/multisite/multisite-verify-jobs.yml b/jjb/multisite/multisite-verify-jobs.yml index e56b62b63..9431e0bac 100644 --- a/jjb/multisite/multisite-verify-jobs.yml +++ b/jjb/multisite/multisite-verify-jobs.yml @@ -57,6 +57,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/netready/netready.yml b/jjb/netready/netready.yml index 382434ae6..9a4d8858c 100644 --- a/jjb/netready/netready.yml +++ b/jjb/netready/netready.yml @@ -44,6 +44,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/octopus/octopus.yml b/jjb/octopus/octopus.yml index cb66112fe..c06fa89e8 100644 --- a/jjb/octopus/octopus.yml +++ b/jjb/octopus/octopus.yml @@ -52,6 +52,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/onosfw/onosfw.yml b/jjb/onosfw/onosfw.yml index 3afcb656e..9d6b037e1 100644 --- a/jjb/onosfw/onosfw.yml +++ b/jjb/onosfw/onosfw.yml @@ -56,6 +56,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/openretriever/openretriever-project.yml b/jjb/openretriever/openretriever-project.yml index 3d53f9b2e..3bcfab6d3 100644 --- a/jjb/openretriever/openretriever-project.yml +++ b/jjb/openretriever/openretriever-project.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/opera/opera-verify-jobs.yml b/jjb/opera/opera-verify-jobs.yml index b7b5cb3c9..4da41d8d9 100644 --- a/jjb/opera/opera-verify-jobs.yml +++ b/jjb/opera/opera-verify-jobs.yml @@ -76,6 +76,7 @@ file-paths: - compare-type: ANT pattern: '**/*' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/opnfvdocs/docs-rtd.yaml b/jjb/opnfvdocs/docs-rtd.yaml index c78e7f0f6..bf6d0012b 100644 --- a/jjb/opnfvdocs/docs-rtd.yaml +++ b/jjb/opnfvdocs/docs-rtd.yaml @@ -7,6 +7,8 @@ stream: - master: branch: 'master' + - danube: + branch: 'stable/{stream}' project: 'opnfvdocs' rtdproject: 'opnfv' @@ -67,7 +69,7 @@ server: 'gerrit.opnfv.org' project: '**' branch: '{branch}' - files: 'docs/**/*.rst' + files: 'docs/**/*.*' - timed: 'H H * * *' builders: diff --git a/jjb/parser/parser.yml b/jjb/parser/parser.yml index 7f3d6cebe..35e97c3b3 100644 --- a/jjb/parser/parser.yml +++ b/jjb/parser/parser.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/jjb/pharos/pharos.yml b/jjb/pharos/pharos.yml index 6dae9f33c..12ae5cabe 100644 --- a/jjb/pharos/pharos.yml +++ b/jjb/pharos/pharos.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/prediction/prediction.yml b/jjb/prediction/prediction.yml index b380d8c86..a153a9bb0 100644 --- a/jjb/prediction/prediction.yml +++ b/jjb/prediction/prediction.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/promise/promise.yml b/jjb/promise/promise.yml index a5aa302c7..eeace5f78 100644 --- a/jjb/promise/promise.yml +++ b/jjb/promise/promise.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/qtip/qtip-verify-jobs.yml b/jjb/qtip/qtip-verify-jobs.yml index 806d7fdff..dd444c7a5 100644 --- a/jjb/qtip/qtip-verify-jobs.yml +++ b/jjb/qtip/qtip-verify-jobs.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/snaps/snaps.yml b/jjb/snaps/snaps.yml index ea8dfb0d2..50b7c3070 100644 --- a/jjb/snaps/snaps.yml +++ b/jjb/snaps/snaps.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/ves/ves.yml b/jjb/ves/ves.yml index 3d3ba2ca8..e6243f32c 100644 --- a/jjb/ves/ves.yml +++ b/jjb/ves/ves.yml @@ -53,6 +53,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**|.gitignore' diff --git a/jjb/vswitchperf/vswitchperf.yml b/jjb/vswitchperf/vswitchperf.yml index 715305bec..c5c81c898 100644 --- a/jjb/vswitchperf/vswitchperf.yml +++ b/jjb/vswitchperf/vswitchperf.yml @@ -97,6 +97,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' @@ -152,6 +153,7 @@ branches: - branch-compare-type: 'ANT' branch-pattern: '**/{branch}' + disable-strict-forbidden-file-verification: 'true' forbidden-file-paths: - compare-type: ANT pattern: 'docs/**' diff --git a/utils/lab-reconfiguration/foreman.yaml b/utils/lab-reconfiguration/foreman.yaml index 48ab9ab6e..0a37be2e1 100644 --- a/utils/lab-reconfiguration/foreman.yaml +++ b/utils/lab-reconfiguration/foreman.yaml @@ -1,3 +1,4 @@ +--- # Vnic configuration for foreman deploy network: diff --git a/utils/lab-reconfiguration/fuel.yaml b/utils/lab-reconfiguration/fuel.yaml index eb9028b2c..15e64c452 100644 --- a/utils/lab-reconfiguration/fuel.yaml +++ b/utils/lab-reconfiguration/fuel.yaml @@ -1,3 +1,4 @@ +--- # Vnic configuration for fuel deploy network: diff --git a/utils/test/dashboard/dashboard/functest/testcases.yaml b/utils/test/dashboard/dashboard/functest/testcases.yaml index 9c33d2e6b..85cb8b292 100644 --- a/utils/test/dashboard/dashboard/functest/testcases.yaml +++ b/utils/test/dashboard/dashboard/functest/testcases.yaml @@ -1,3 +1,4 @@ +--- functest: - name: tempest_smoke_serial diff --git a/utils/test/dashboard/dashboard/qtip/testcases.yaml b/utils/test/dashboard/dashboard/qtip/testcases.yaml index cd337cd73..dfa9cc2db 100644 --- a/utils/test/dashboard/dashboard/qtip/testcases.yaml +++ b/utils/test/dashboard/dashboard/qtip/testcases.yaml @@ -1,3 +1,4 @@ +--- qtip: - name: compute_test_suite @@ -18,7 +19,7 @@ qtip: fields: - field: details.index - - name:storage_test_suite + name: storage_test_suite format: qpi test_family: storage visualizations: diff --git a/utils/test/reporting/reporting.yaml b/utils/test/reporting/reporting.yaml index 33c7cc257..8c5ce1383 100644 --- a/utils/test/reporting/reporting.yaml +++ b/utils/test/reporting/reporting.yaml @@ -1,3 +1,4 @@ +--- general: installers: - apex @@ -20,12 +21,12 @@ general: directories: # Relative to the path where the repo is cloned: - dir_reporting: utils/tests/reporting/ - dir_log: utils/tests/reporting/log/ - dir_conf: utils/tests/reporting/conf/ - dir_utils: utils/tests/reporting/utils/ - dir_templates: utils/tests/reporting/templates/ - dir_display: utils/tests/reporting/display/ + dir_reporting: utils/tests/reporting/ + dir_log: utils/tests/reporting/log/ + dir_conf: utils/tests/reporting/conf/ + dir_utils: utils/tests/reporting/utils/ + dir_templates: utils/tests/reporting/templates/ + dir_display: utils/tests/reporting/display/ url: testresults.opnfv.org/reporting/ @@ -49,8 +50,8 @@ functest: test_conf: https://git.opnfv.org/cgit/functest/plain/functest/ci/testcases.yaml log_level: ERROR jenkins_url: https://build.opnfv.org/ci/view/functest/job/ - exclude_noha: False - exclude_virtual: False + exclude_noha: "False" + exclude_virtual: "False" yardstick: test_conf: https://git.opnfv.org/cgit/yardstick/plain/tests/ci/report_config.yaml @@ -58,7 +59,7 @@ yardstick: storperf: test_list: - - snia_steady_state + - snia_steady_state log_level: ERROR qtip: diff --git a/utils/test/testapi/update/test.yml b/utils/test/testapi/update/test.yml index a8868720d..943105c5f 100644 --- a/utils/test/testapi/update/test.yml +++ b/utils/test/testapi/update/test.yml @@ -1,7 +1,7 @@ --- - hosts: "{{ host }}" remote_user: "{{ user }}" - become: yes + become: "yes" become_method: sudo vars: user: "root" diff --git a/utils/test/testapi/update/update.yml b/utils/test/testapi/update/update.yml index e6663d905..18b75b6bf 100644 --- a/utils/test/testapi/update/update.yml +++ b/utils/test/testapi/update/update.yml @@ -1,7 +1,7 @@ --- - hosts: "{{ host }}" remote_user: "{{ user }}" - become: yes + become: "yes" become_method: sudo vars: user: "root" @@ -47,4 +47,4 @@ - name: remove temporary update directory file: path: "{{ update_path }}" - state: absent
\ No newline at end of file + state: absent diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/README.md b/utils/test/vnfcatalogue/VNF_Catalogue/README.md index 32ad65416..22d429072 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/README.md +++ b/utils/test/vnfcatalogue/VNF_Catalogue/README.md @@ -5,8 +5,13 @@ First install the dependencies - ```npm install``` + ```npm install``` + +set time zone(Important) + Set same timezone in both nodejs server and mysql server. Something + similar to below can be used: + ``` SET GLOBAL time_zone = '+00:00'; ``` Then Start the Server - ```npm start``` + ```npm start``` diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/app.js b/utils/test/vnfcatalogue/VNF_Catalogue/app.js index 0f842b62d..4b6add2be 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/app.js +++ b/utils/test/vnfcatalogue/VNF_Catalogue/app.js @@ -13,9 +13,17 @@ var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); +var validator = require('express-validator'); var routes = require('./routes/index'); var search_projects = require('./routes/search_projects'); +var project_profile = require('./routes/project_profile'); +var add_project = require('./routes/add_project'); +var add_tag = require('./routes/add_tag'); +var search_tag = require('./routes/search_tag'); +var search_vnf = require('./routes/search_vnf'); +var vnf_tag_association = require('./routes/vnf_tag_association'); + var app = express(); @@ -23,27 +31,35 @@ var app = express(); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); +db_pool = require('./database').pool; + // Database -var db = require('mysql2'); +//var db = require('mysql2'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); +app.use(validator()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // Make our db accessible to our router app.use(function(req,res,next){ - req.db = db; + //db_pool size 50 default + req.db_pool = db_pool; next(); }); app.use('/', routes); app.use('/search_projects', search_projects); - - +app.use('/project_profile', project_profile); +app.use('/add_project', add_project); +app.use('/add_tag', add_tag); +app.use('/search_tag', search_tag); +app.use('/search_vnf', search_vnf); +app.use('/vnf_tag_association', vnf_tag_association); // Some Error handling for now #TODO Remove /// catch 404 and forwarding to error handler diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/database.js b/utils/test/vnfcatalogue/VNF_Catalogue/database.js new file mode 100644 index 000000000..b31310480 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/database.js @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var mysql = require('mysql'); + +var pool = mysql.createPool({ + host: 'localhost', + user: 'myuser', + password: 'mypassword', + database: 'vnf_catalogue', + connectionLimit: 50, + supportBigNumbers: true, + multipleStatements: true, + dateStrings: 'date' +}); + +exports.pool = pool; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/package.json b/utils/test/vnfcatalogue/VNF_Catalogue/package.json index 7c6a86730..414b42425 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/package.json +++ b/utils/test/vnfcatalogue/VNF_Catalogue/package.json @@ -13,6 +13,11 @@ "jade": "~1.11.0", "morgan": "~1.7.0", "serve-favicon": "~2.3.0", - "mysql2": "*" + "mysql": "*", + "express-validator": "*", + "nodemon": "*", + "async": "*", + "multer": "*", + "octonode": "*" } -}
\ No newline at end of file +} diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js new file mode 100644 index 000000000..11235e75b --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js @@ -0,0 +1,7 @@ +/*! + * typeahead.js 0.10.4 + * https://github.com/twitter/typeahead.js + * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT + */ + +!function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},noop:function(){}}}(),c="0.10.4",d=function(){"use strict";function a(a){return a=b.toStr(a),a?a.split(/\s+/):[]}function c(a){return a=b.toStr(a),a?a.split(/\W+/):[]}function d(a){return function(){var c=[].slice.call(arguments,0);return function(d){var e=[];return b.each(c,function(c){e=e.concat(a(b.toStr(d[c])))}),e}}}return{nonword:c,whitespace:a,obj:{nonword:d(c),whitespace:d(a)}}}(),e=function(){"use strict";function c(c){this.maxSize=b.isNumber(c)?c:100,this.reset(),this.maxSize<=0&&(this.set=this.get=a.noop)}function d(){this.head=this.tail=null}function e(a,b){this.key=a,this.val=b,this.prev=this.next=null}return b.mixin(c.prototype,{set:function(a,b){var c,d=this.list.tail;this.size>=this.maxSize&&(this.list.remove(d),delete this.hash[d.key]),(c=this.hash[a])?(c.val=b,this.list.moveToFront(c)):(c=new e(a,b),this.list.add(c),this.hash[a]=c,this.size++)},get:function(a){var b=this.hash[a];return b?(this.list.moveToFront(b),b.val):void 0},reset:function(){this.size=0,this.hash={},this.list=new d}}),b.mixin(d.prototype,{add:function(a){this.head&&(a.next=this.head,this.head.prev=a),this.head=a,this.tail=this.tail||a},remove:function(a){a.prev?a.prev.next=a.next:this.head=a.next,a.next?a.next.prev=a.prev:this.tail=a.prev},moveToFront:function(a){this.remove(a),this.add(a)}}),c}(),f=function(){"use strict";function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+b.escapeRegExChars(this.prefix))}function c(){return(new Date).getTime()}function d(a){return JSON.stringify(b.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return b.isNumber(g)?f.setItem(this._ttlKey(a),d(c()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return b.isNumber(d)&&c()>d?!0:!1}}:{get:b.noop,set:b.noop,remove:b.noop,clear:b.noop,isExpired:b.noop},b.mixin(a.prototype,g),a}(),g=function(){"use strict";function c(b){b=b||{},this.cancelled=!1,this.lastUrl=null,this._send=b.transport?d(b.transport):a.ajax,this._get=b.rateLimiter?b.rateLimiter(this._get):this._get,this._cache=b.cache===!1?new e(0):i}function d(c){return function(d,e){function f(a){b.defer(function(){h.resolve(a)})}function g(a){b.defer(function(){h.reject(a)})}var h=a.Deferred();return c(d,e,f,g),h}}var f=0,g={},h=6,i=new e(10);return c.setMaxPendingRequests=function(a){h=a},c.resetCache=function(){i.reset()},b.mixin(c.prototype,{_get:function(a,b,c){function d(b){c&&c(null,b),k._cache.set(a,b)}function e(){c&&c(!0)}function i(){f--,delete g[a],k.onDeckRequestArgs&&(k._get.apply(k,k.onDeckRequestArgs),k.onDeckRequestArgs=null)}var j,k=this;this.cancelled||a!==this.lastUrl||((j=g[a])?j.done(d).fail(e):h>f?(f++,g[a]=this._send(a,b).done(d).fail(e).always(i)):this.onDeckRequestArgs=[].slice.call(arguments,0))},get:function(a,c,d){var e;return b.isFunction(c)&&(d=c,c={}),this.cancelled=!1,this.lastUrl=a,(e=this._cache.get(a))?b.defer(function(){d&&d(null,e)}):this._get(a,c,d),!!e},cancel:function(){this.cancelled=!0}}),c}(),h=function(){"use strict";function c(b){b=b||{},b.datumTokenizer&&b.queryTokenizer||a.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=b.datumTokenizer,this.queryTokenizer=b.queryTokenizer,this.reset()}function d(a){return a=b.filter(a,function(a){return!!a}),a=b.map(a,function(a){return a.toLowerCase()})}function e(){return{ids:[],children:{}}}function f(a){for(var b={},c=[],d=0,e=a.length;e>d;d++)b[a[d]]||(b[a[d]]=!0,c.push(a[d]));return c}function g(a,b){function c(a,b){return a-b}var d=0,e=0,f=[];a=a.sort(c),b=b.sort(c);for(var g=a.length,h=b.length;g>d&&h>e;)a[d]<b[e]?d++:a[d]>b[e]?e++:(f.push(a[d]),d++,e++);return f}return b.mixin(c.prototype,{bootstrap:function(a){this.datums=a.datums,this.trie=a.trie},add:function(a){var c=this;a=b.isArray(a)?a:[a],b.each(a,function(a){var f,g;f=c.datums.push(a)-1,g=d(c.datumTokenizer(a)),b.each(g,function(a){var b,d,g;for(b=c.trie,d=a.split("");g=d.shift();)b=b.children[g]||(b.children[g]=e()),b.ids.push(f)})})},get:function(a){var c,e,h=this;return c=d(this.queryTokenizer(a)),b.each(c,function(a){var b,c,d,f;if(e&&0===e.length)return!1;for(b=h.trie,c=a.split("");b&&(d=c.shift());)b=b.children[d];return b&&0===c.length?(f=b.ids.slice(0),void(e=e?g(e,f):f)):(e=[],!1)}),e?b.map(f(e),function(a){return h.datums[a]}):[]},reset:function(){this.datums=[],this.trie=e()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),c}(),i=function(){"use strict";function d(a){return a.local||null}function e(d){var e,f;return f={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(e=d.prefetch||null)&&(e=b.isString(e)?{url:e}:e,e=b.mixin(f,e),e.thumbprint=c+e.thumbprint,e.ajax.type=e.ajax.type||"GET",e.ajax.dataType=e.ajax.dataType||"json",!e.url&&a.error("prefetch requires url to be set")),e}function f(c){function d(a){return function(c){return b.debounce(c,a)}}function e(a){return function(c){return b.throttle(c,a)}}var f,g;return g={url:null,cache:!0,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(f=c.remote||null)&&(f=b.isString(f)?{url:f}:f,f=b.mixin(g,f),f.rateLimiter=/^throttle$/i.test(f.rateLimitBy)?e(f.rateLimitWait):d(f.rateLimitWait),f.ajax.type=f.ajax.type||"GET",f.ajax.dataType=f.ajax.dataType||"json",delete f.rateLimitBy,delete f.rateLimitWait,!f.url&&a.error("remote requires url to be set")),f}return{local:d,prefetch:e,remote:f}}();!function(c){"use strict";function e(b){b&&(b.local||b.prefetch||b.remote)||a.error("one of local, prefetch, or remote is required"),this.limit=b.limit||5,this.sorter=j(b.sorter),this.dupDetector=b.dupDetector||k,this.local=i.local(b),this.prefetch=i.prefetch(b),this.remote=i.remote(b),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new h({datumTokenizer:b.datumTokenizer,queryTokenizer:b.queryTokenizer}),this.storage=this.cacheKey?new f(this.cacheKey):null}function j(a){function c(b){return b.sort(a)}function d(a){return a}return b.isFunction(a)?c:d}function k(){return!1}var l,m;return l=c.Bloodhound,m={data:"data",protocol:"protocol",thumbprint:"thumbprint"},c.Bloodhound=e,e.noConflict=function(){return c.Bloodhound=l,e},e.tokenizers=d,b.mixin(e.prototype,{_loadPrefetch:function(b){function c(a){f.clear(),f.add(b.filter?b.filter(a):a),f._saveToStorage(f.index.serialize(),b.thumbprint,b.ttl)}var d,e,f=this;return(d=this._readFromStorage(b.thumbprint))?(this.index.bootstrap(d),e=a.Deferred().resolve()):e=a.ajax(b.url,b.ajax).done(c),e},_getFromRemote:function(a,b){function c(a,c){b(a?[]:f.remote.filter?f.remote.filter(c):c)}var d,e,f=this;if(this.transport)return a=a||"",e=encodeURIComponent(a),d=this.remote.replace?this.remote.replace(this.remote.url,a):this.remote.url.replace(this.remote.wildcard,e),this.transport.get(d,this.remote.ajax,c)},_cancelLastRemoteRequest:function(){this.transport&&this.transport.cancel()},_saveToStorage:function(a,b,c){this.storage&&(this.storage.set(m.data,a,c),this.storage.set(m.protocol,location.protocol,c),this.storage.set(m.thumbprint,b,c))},_readFromStorage:function(a){var b,c={};return this.storage&&(c.data=this.storage.get(m.data),c.protocol=this.storage.get(m.protocol),c.thumbprint=this.storage.get(m.thumbprint)),b=c.thumbprint!==a||c.protocol!==location.protocol,c.data&&!b?c.data:null},_initialize:function(){function c(){e.add(b.isFunction(f)?f():f)}var d,e=this,f=this.local;return d=this.prefetch?this._loadPrefetch(this.prefetch):a.Deferred().resolve(),f&&d.done(c),this.transport=this.remote?new g(this.remote):null,this.initPromise=d.promise()},initialize:function(a){return!this.initPromise||a?this._initialize():this.initPromise},add:function(a){this.index.add(a)},get:function(a,c){function d(a){var d=f.slice(0);b.each(a,function(a){var c;return c=b.some(d,function(b){return e.dupDetector(a,b)}),!c&&d.push(a),d.length<e.limit}),c&&c(e.sorter(d))}var e=this,f=[],g=!1;f=this.index.get(a),f=this.sorter(f).slice(0,this.limit),f.length<this.limit?g=this._getFromRemote(a,d):this._cancelLastRemoteRequest(),g||(f.length>0||!this.transport)&&c&&c(f)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&g.resetCache()},ttAdapter:function(){return b.bind(this.get,this)}}),e}(this);var j=function(){return{wrapper:'<span class="twitter-typeahead"></span>',dropdown:'<span class="tt-dropdown-menu"></span>',dataset:'<div class="tt-dataset-%CLASS%"></div>',suggestions:'<span class="tt-suggestions"></span>',suggestion:'<div class="tt-suggestion"></div>'}}(),k=function(){"use strict";var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),b.isMsie()&&b.isMsie()<=7&&b.mixin(a.input,{marginTop:"-1px"}),a}(),l=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return b.mixin(c.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),c}(),m=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),n=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e<a.childNodes.length;e++)c=a.childNodes[e],c.nodeType===d?e+=b(c)?1:0:g(c,b)}var h;e=b.mixin({},d,e),e.node&&e.pattern&&(e.pattern=b.isArray(e.pattern)?e.pattern:[e.pattern],h=c(e.pattern,e.caseSensitive,e.wordsOnly),g(e.node,f))}}(window.document),o=function(){"use strict";function c(c){var e,f,h,i,j=this;c=c||{},c.input||a.error("input is missing"),e=b.bind(this._onBlur,this),f=b.bind(this._onFocus,this),h=b.bind(this._onKeydown,this),i=b.bind(this._onInput,this),this.$hint=a(c.hint),this.$input=a(c.input).on("blur.tt",e).on("focus.tt",f).on("keydown.tt",h),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop),b.isMsie()?this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){g[a.which||a.keyCode]||b.defer(b.bind(j._onInput,j,a))}):this.$input.on("input.tt",i),this.query=this.$input.val(),this.$overflowHelper=d(this.$input)}function d(b){return a('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function e(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function f(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var g;return g={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,m,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(a){var b=g[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(a,b){var c,d,e;switch(a){case"tab":d=this.getHint(),e=this.getInputValue(),c=d&&d!==e&&!f(b);break;case"up":case"down":c=!f(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!f(b);break;default:c=!0}return c},_checkInputValue:function(){var a,b,c;a=this.getInputValue(),b=e(a,this.query),c=b?this.query.length!==a.length:!1,this.query=a,b?c&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),b?this.clearHint():this._checkInputValue()},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null}}),c}(),p=function(){"use strict";function c(c){c=c||{},c.templates=c.templates||{},c.source||a.error("missing source"),c.name&&!f(c.name)&&a.error("invalid dataset name: "+c.name),this.query=null,this.highlight=!!c.highlight,this.name=c.name||b.getUniqueId(),this.source=c.source,this.displayFn=d(c.display||c.displayKey),this.templates=e(c.templates,this.displayFn),this.$el=a(j.dataset.replace("%CLASS%",this.name))}function d(a){function c(b){return b[a]}return a=a||"value",b.isFunction(a)?a:c}function e(a,c){function d(a){return"<p>"+c(a)+"</p>"}return{empty:a.empty&&b.templatify(a.empty),header:a.header&&b.templatify(a.header),footer:a.footer&&b.templatify(a.footer),suggestion:a.suggestion||d}}function f(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var g="ttDataset",h="ttValue",i="ttDatum";return c.extractDatasetName=function(b){return a(b).data(g)},c.extractValue=function(b){return a(b).data(h)},c.extractDatum=function(b){return a(b).data(i)},b.mixin(c.prototype,m,{_render:function(c,d){function e(){return p.templates.empty({query:c,isEmpty:!0})}function f(){function e(b){var c;return c=a(j.suggestion).append(p.templates.suggestion(b)).data(g,p.name).data(h,p.displayFn(b)).data(i,b),c.children().each(function(){a(this).css(k.suggestionChild)}),c}var f,l;return f=a(j.suggestions).css(k.suggestions),l=b.map(d,e),f.append.apply(f,l),p.highlight&&n({className:"tt-highlight",node:f[0],pattern:c}),f}function l(){return p.templates.header({query:c,isEmpty:!o})}function m(){return p.templates.footer({query:c,isEmpty:!o})}if(this.$el){var o,p=this;this.$el.empty(),o=d&&d.length,!o&&this.templates.empty?this.$el.html(e()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null):o&&this.$el.html(f()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null),this.trigger("rendered")}},getRoot:function(){return this.$el},update:function(a){function b(b){c.canceled||a!==c.query||c._render(a,b)}var c=this;this.query=a,this.canceled=!1,this.source(a,b)},cancel:function(){this.canceled=!0},clear:function(){this.cancel(),this.$el.empty(),this.trigger("rendered")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=null}}),c}(),q=function(){"use strict";function c(c){var e,f,g,h=this;c=c||{},c.menu||a.error("menu is required"),this.isOpen=!1,this.isEmpty=!0,this.datasets=b.map(c.datasets,d),e=b.bind(this._onSuggestionClick,this),f=b.bind(this._onSuggestionMouseEnter,this),g=b.bind(this._onSuggestionMouseLeave,this),this.$menu=a(c.menu).on("click.tt",".tt-suggestion",e).on("mouseenter.tt",".tt-suggestion",f).on("mouseleave.tt",".tt-suggestion",g),b.each(this.datasets,function(a){h.$menu.append(a.getRoot()),a.onSync("rendered",h._onRendered,h)})}function d(a){return new p(a)}return b.mixin(c.prototype,m,{_onSuggestionClick:function(b){this.trigger("suggestionClicked",a(b.currentTarget))},_onSuggestionMouseEnter:function(b){this._removeCursor(),this._setCursor(a(b.currentTarget),!0)},_onSuggestionMouseLeave:function(){this._removeCursor()},_onRendered:function(){function a(a){return a.isEmpty()}this.isEmpty=b.every(this.datasets,a),this.isEmpty?this._hide():this.isOpen&&this._show(),this.trigger("datasetRendered")},_hide:function(){this.$menu.hide()},_show:function(){this.$menu.css("display","block")},_getSuggestions:function(){return this.$menu.find(".tt-suggestion")},_getCursor:function(){return this.$menu.find(".tt-cursor").first()},_setCursor:function(a,b){a.first().addClass("tt-cursor"),!b&&this.trigger("cursorMoved")},_removeCursor:function(){this._getCursor().removeClass("tt-cursor")},_moveCursor:function(a){var b,c,d,e;if(this.isOpen){if(c=this._getCursor(),b=this._getSuggestions(),this._removeCursor(),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return void this.trigger("cursorRemoved");-1>d&&(d=b.length-1),this._setCursor(e=b.eq(d)),this._ensureVisible(e)}},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$menu.scrollTop(),e=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),0>b?this.$menu.scrollTop(d+b):c>e&&this.$menu.scrollTop(d+(c-e))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){this.$menu.css("ltr"===a?k.ltr:k.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(a){var b=null;return a.length&&(b={raw:p.extractDatum(a),value:p.extractValue(a),datasetName:p.extractDatasetName(a)}),b},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},update:function(a){function c(b){b.update(a)}b.each(this.datasets,c)},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){function a(a){a.destroy()}this.$menu.off(".tt"),this.$menu=null,b.each(this.datasets,a)}}),c}(),r=function(){"use strict";function c(c){var e,f,g;c=c||{},c.input||a.error("missing input"),this.isActivated=!1,this.autoselect=!!c.autoselect,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.$node=d(c.input,c.withHint),e=this.$node.find(".tt-dropdown-menu"),f=this.$node.find(".tt-input"),g=this.$node.find(".tt-hint"),f.on("blur.tt",function(a){var c,d,g;c=document.activeElement,d=e.is(c),g=e.has(c).length>0,b.isMsie()&&(d||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){f.focus()}))}),e.on("mousedown.tt",function(a){a.preventDefault()}),this.eventBus=c.eventBus||new l({el:f}),this.dropdown=new q({menu:e,datasets:c.datasets}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new o({input:f,hint:g}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._setLanguageDirection()}function d(b,c){var d,f,h,i;d=a(b),f=a(j.wrapper).css(k.wrapper),h=a(j.dropdown).css(k.dropdown),i=d.clone().css(k.hint).css(e(d)),i.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly",!0).attr({autocomplete:"off",spellcheck:"false",tabindex:-1}),d.data(g,{dir:d.attr("dir"),autocomplete:d.attr("autocomplete"),spellcheck:d.attr("spellcheck"),style:d.attr("style")}),d.addClass("tt-input").attr({autocomplete:"off",spellcheck:!1}).css(c?k.input:k.inputWithNoHint);try{!d.attr("dir")&&d.attr("dir","auto")}catch(l){}return d.wrap(f).parent().prepend(c?i:null).append(h)}function e(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function f(a){var c=a.find(".tt-input");b.each(c.data(g),function(a,d){b.isUndefined(a)?c.removeAttr(d):c.attr(d,a)}),c.detach().removeData(g).removeClass("tt-input").insertAfter(a),a.remove()}var g="ttAttrs";return b.mixin(c.prototype,{_onSuggestionClicked:function(a,b){var c;(c=this.dropdown.getDatumForSuggestion(b))&&this._select(c)},_onCursorMoved:function(){var a=this.dropdown.getDatumForCursor();this.input.setInputValue(a.value,!0),this.eventBus.trigger("cursorchanged",a.raw,a.datasetName)},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint()},_onDatasetRendered:function(){this._updateHint()},_onOpened:function(){this._updateHint(),this.eventBus.trigger("opened")},_onClosed:function(){this.input.clearHint(),this.eventBus.trigger("closed")},_onFocused:function(){this.isActivated=!0,this.dropdown.open()},_onBlurred:function(){this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()},_onEnterKeyed:function(a,b){var c,d;c=this.dropdown.getDatumForCursor(),d=this.dropdown.getDatumForTopSuggestion(),c?(this._select(c),b.preventDefault()):this.autoselect&&d&&(this._select(d),b.preventDefault())},_onTabKeyed:function(a,b){var c;(c=this.dropdown.getDatumForCursor())?(this._select(c),b.preventDefault()):this._autocomplete(!0)},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(a,b){this.input.clearHintIfInvalid(),b.length>=this.minLength?this.dropdown.update(b):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var a;this.dir!==(a=this.input.getLanguageDirection())&&(this.dir=a,this.$node.css("direction",a),this.dropdown.setLanguageDirection(a))},_updateHint:function(){var a,c,d,e,f,g;a=this.dropdown.getDatumForTopSuggestion(),a&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(c=this.input.getInputValue(),d=o.normalizeQuery(c),e=b.escapeRegExChars(d),f=new RegExp("^(?:"+e+")(.+$)","i"),g=f.exec(a.value),g?this.input.setHint(c+g[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(a){var b,c,d,e;b=this.input.getHint(),c=this.input.getQuery(),d=a||this.input.isCursorAtEnd(),b&&c!==b&&d&&(e=this.dropdown.getDatumForTopSuggestion(),e&&this.input.setInputValue(e.value),this.eventBus.trigger("autocompleted",e.raw,e.datasetName))},_select:function(a){this.input.setQuery(a.value),this.input.setInputValue(a.value,!0),this._setLanguageDirection(),this.eventBus.trigger("selected",a.raw,a.datasetName),this.dropdown.close(),b.defer(b.bind(this.dropdown.empty,this.dropdown))},open:function(){this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(a){a=b.toStr(a),this.isActivated?this.input.setInputValue(a):(this.input.setQuery(a),this.input.setInputValue(a,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),f(this.$node),this.$node=null}}),c}();!function(){"use strict";var c,d,e;c=a.fn.typeahead,d="ttTypeahead",e={initialize:function(c,e){function f(){var f,g,h=a(this);b.each(e,function(a){a.highlight=!!c.highlight}),g=new r({input:h,eventBus:f=new l({el:h}),withHint:b.isUndefined(c.hint)?!0:!!c.hint,minLength:c.minLength,autoselect:c.autoselect,datasets:e}),h.data(d,g)}return e=b.isArray(e)?e:[].slice.call(arguments,1),c=c||{},this.each(f)},open:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.open()}return this.each(b)},close:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.close()}return this.each(b)},val:function(b){function c(){var c,e=a(this);(c=e.data(d))&&c.setVal(b)}function e(a){var b,c;return(b=a.data(d))&&(c=b.getVal()),c}return arguments.length?this.each(c):e(this.first())},destroy:function(){function b(){var b,c=a(this);(b=c.data(d))&&(b.destroy(),c.removeData(d))}return this.each(b)}},a.fn.typeahead=function(b){var c;return e[b]&&"initialize"!==b?(c=this.filter(function(){return!!a(this).data(d)}),e[b].apply(c,[].slice.call(arguments,1))):e.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=c,this}}()}(window.jQuery);
\ No newline at end of file diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js index 3ae20d1a9..f610456e1 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js @@ -8,20 +8,80 @@ *******************************************************************************/
$(document).ready( function() {
+ $('select').material_select();
+ $('.modal').modal();
$(".button-collapse").sideNav();
+ $('.carousel').carousel();
+
$('#Search').click(function() {
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
$('#SearchSpan').click(function(){
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
$('div.form-group-custom i.material-icons').click(function(e){
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
+ $("#add_project_button").on('click',function(){
+ event.preventDefault();
+ var vnf_name = $("#vnf_name").val() ;
+
+ var formData = new FormData($('form#add_project_form')[0]);
+ var license = $('#license option:selected').val();
+ formData.append('license', license);
+ var opnfv_indicator = $('#opnfv_indicator option:selected').val();
+ formData.append('opnfv_indicator', opnfv_indicator);
+
+ $.ajax({
+ url: '/add_project',
+ type: 'post',
+ //dataType: 'json',
+ processData: false, // tell jQuery not to process the data
+ contentType: false, // tell jQuery not to set contentType
+ data: formData,
+ success: function(data) {
+ $('#modal1').modal('close');
+ $('form#add_project_form').trigger('reset');
+ Materialize.toast('Successfully submitted the VNF!', 3000, 'rounded');
+ },
+ error: function (error) {
+ if(error['responseJSON']) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ } else if(error['responseText']) {
+ var response_message = JSON.parse(error['responseText']);
+ Materialize.toast(response_message['error'], 3000, 'rounded');
+ }
+ //$('#modal1').modal('open');
+ }
+ });
+ });
+ $("#add_tag_button").on('click',function(){
+ event.preventDefault();
+ var tag_name = $("#tag_name").val() ;
+
+ $.ajax({
+ url: '/add_tag',
+ type: 'post',
+ dataType: 'json',
+ data: $('form#add_tag_form').serialize(),
+ success: function(data) {
+ $('#modal2').modal('close');
+ $('form#add_tag_form').trigger('reset');
+ Materialize.toast('Successfully submitted the TAG!', 3000, 'rounded');
+ },
+ error: function (error) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ }
+ });
+ });
+
});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js new file mode 100644 index 000000000..2047a92a8 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js @@ -0,0 +1,82 @@ +/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+$(document).ready( function() {
+
+ //getVnfs : get 5 main VNFs using typeahead
+ var getVnfs = new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),
+ queryTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),
+ remote: {
+ url: '/search_vnf?key=%QUERY',
+ wildcard: '%QUERY'
+ },
+ limit: 5
+ });
+
+ getVnfs.initialize();
+ $('#scrollable-dropdown-menu #vnf_name.typeahead').typeahead(
+ {
+ hint: true,
+ highlight: true,
+ minLength: 1
+ },
+ {
+ name: 'vnf_name',
+ display: 'vnf_name',
+ limit: 5,
+ source: getVnfs.ttAdapter()
+ });
+
+ //getTags : get 5 main tags using typeahead
+ var getTags = new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),
+ queryTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),
+ remote: {
+ url: '/search_tag?key=%QUERY',
+ wildcard: '%QUERY'
+ },
+ limit: 5
+ });
+
+ getTags.initialize();
+ $('#scrollable-dropdown-menu #tag_name.typeahead').typeahead(
+ {
+ hint: true,
+ highlight: true,
+ minLength: 1
+ },
+ {
+ name: 'tag_name',
+ display: 'tag_name',
+ limit: 5,
+ source: getTags.ttAdapter()
+ });
+
+ $("#add_vnf_tag_association_button").on('click',function(){
+ event.preventDefault();
+ var vnf_name = $("#vnf_name").val() ;
+
+ $.ajax({
+ url: '/vnf_tag_association',
+ type: 'post',
+ dataType: 'json',
+ data: $('form#add_vnf_tag_association_form').serialize(),
+ success: function(data) {
+ $('#modal3').modal('close');
+ $('form#add_vnf_tag_association_form').trigger('reset');
+ Materialize.toast('Successfully added the TAG to the VNF!', 3000, 'rounded');
+ },
+ error: function (error) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ }
+ });
+ });
+
+});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js new file mode 100644 index 000000000..26c28c945 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js @@ -0,0 +1,12 @@ +/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+$(document).ready( function() {
+ var ob = JSON.parse(json);
+});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css new file mode 100644 index 000000000..03527f088 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +.container-custom { + max-width: 100% !important; +} diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css new file mode 100644 index 000000000..4598cffec --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +input.search-input-rest +{ + font-weight: 400; + margin: 0px 0; + height: 30px; + padding: 10px 30px; + min-width: 90%; + max-width: 90%; + /*max-width: 500px; + */ + border-radius: 5px; + border: 2px solid #333333; + box-shadow: 0 0 15px 1px rgba(0,0,0,0.50); + color: #333333; + font-size: 22px; +} +.material-search-custom { + left : -30px; + + padding-left: 10px; +} +.form-group-custom { + width : 400px; + position: relative; + float: right; + left: -40%; +} +.form-control-custom { + padding-top: 10px; + padding-left: 50px; +} +input[type="search"]:focus:not([readonly]) { + transition: all 0s !important; + border-radius: 5px; + border: 2px solid #333333; + box-shadow: 0 0 15px 1px rgba(0,0,0,0.50); + color: #333333; +} +.gray { + background: rgb(249,249,249); +} +span.glyphicon.glyphicon-search.form-control-feedback, + div.form-group-custom i.material-icons { + top: 0.5em; + left: 16.0em; + cursor:pointer; + z-index: 30; + position: absolute; +} diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css index 8875f7fe5..c00071160 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css @@ -7,36 +7,13 @@ * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ -input[type="text"]:focus:not([readonly]) { - transition: all 0s !important; - border-radius: 5px; - border: 2px solid #333333; - box-shadow: 0 0 15px 1px rgba(0,0,0,0.50); - color: #333333; -} -.gray { - background: rgb(249,249,249); -} -.material-search-custom { - left : -30px; - - padding-left: 10px; -} -.form-group-custom { - width : 400px; - position: relative; - float: right; - left: -40%; -} -.form-control-custom { - padding-top: 10px; - padding-left: 50px; -} .card-shadow-custom { box-shadow: 0 2px 3px 0 rgba(0,0,0,0.50); border-bottom: 2px solid #8B19A2; } .row-custom { + display: flex; + flex-flow: row wrap; width: 100%; margin: 1em 1em 1em 1em; padding-right: 20px; @@ -56,8 +33,7 @@ input[type="text"]:focus:not([readonly]) { display: inline-block; } .card-image-picture-custom { - margin: 1em 0em 0em 3.5em; - display: inline-block; + margin: auto; } .collection .collection-item.active { background-color: rgb(255,245,114); @@ -125,8 +101,12 @@ a.a-custom-more:hover { span.glyphicon.glyphicon-search.form-control-feedback, div.form-group-custom i.material-icons { top: 0.5em; - left: 16.5em; + left: 16.0em; cursor:pointer; z-index: 30; position: absolute; } +.card-image-custom { + display: flex; + flex-flow: column wrap; +} diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css index 4769cfcc0..f5355ba9d 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css @@ -152,23 +152,6 @@ form.search-form input.search-input color: #333333; font-size: 22px; } -input.search-input-rest -{ - font-weight: 400; - margin: 0px 0; - height: 30px; - padding: 10px 30px; - min-width: 90%; - max-width: 90%; - /*max-width: 500px; - */ - border-radius: 5px; - border: 2px solid #333333; - box-shadow: 0 0 15px 1px rgba(0,0,0,0.50); - color: #333333; - font-size: 22px; -} - form.search-form button.search-button { @@ -306,7 +289,7 @@ footer { height: 100px; } -input[type="text"]:focus:not([readonly]) { +input[type="search"]:focus:not([readonly]) { transition: all 0s !important; border-radius: 5px; border: 2px solid #333333; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png Binary files differnew file mode 100644 index 000000000..fe18194ec --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js new file mode 100644 index 000000000..229620d20 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); +var multer = require('multer'); + + +var storage = multer.diskStorage({ + destination: function (req, file, callback) { + callback(null, './public/uploads'); + }, + filename: function (req, file, callback) { + console.log(file); + console.log(req.body); + callback(null, file.fieldname + '-' + Date.now() + '.jpg'); + } +}); + +var fileFilter = function (req, file, cb) { + if (file.mimetype !== 'image/png') { + //req.fileValidationError = 'goes wrong on the mimetype'; + cb(null, false); + } else { + cb(null, true); + } +} + +var upload = multer({ fileFilter: fileFilter, storage : storage}).single('file_upload'); + + +router.post('/', function(req, res) { + upload(req,res,function(err) { + console.log(req.body); + console.log(req.file) + if(req.file == null && req.body['file_url'] != '') { + response = 'File Upload error: wrong Filetype'; + res.status(500); + res.end(JSON.stringify({'error': response})); + + } + if(err) { + console.log(err); + response = 'File Upload error: ' + err; + console.log(response); + //return res.end(req.fileValidationError); + res.status(500); + res.send({'error': response}); + return; + } + + console.log(req.file); + req.body['photo_url'] = (req.file) ? req.file['filename'] : 'logo.png'; + console.log(req.body); + + req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty(); + req.checkBody("repo_url", "Repository URL must not be empty").notEmpty(); + req.checkBody("license", "Please select a License").notEmpty(); + req.checkBody("opnfv_indicator", "Please select an OPNFV Indicator").notEmpty(); + req.checkBody("repo_url", "Must be a Github URL").matches('.*github\.com.*'); + + var errors = req.validationErrors(); + console.log(errors); + + var response = ''; for(var i = 0; i < errors.length; i++) { + console.log(errors[i]['msg']); + response = response + errors[i]['msg'] + '; '; + } + + if(errors) { res.status(500); + res.send({'error': response}); + return; + } + + var vnf_details = req.body; + delete vnf_details.file_url; + + db_pool.getConnection(function(err, connection) { + // Use the connection + + sql_query = 'INSERT INTO photo(photo_url) values(\'' + req.body['photo_url'] + '\')\;SELECT LAST_INSERT_ID() photo_id'; + // TODO look above query prone to sql_injections + + console.log(sql_query); + connection.query(sql_query, function (error, results, fields) { + console.log('hola'); + console.log(results[1][0].photo_id); + //connection.query(sql_query, vnf_details, function (error, results, fields) { + delete vnf_details.photo_url; + vnf_details['photo_id'] = results[1][0].photo_id; + sql_query = 'INSERT INTO vnf SET ?' + connection.query(sql_query, vnf_details, function (error, results, fields) { + // And done with the connection. + connection.release(); + if (error) throw error; + + // Handle error after the release. + res.end('{"success" : "Updated Successfully", "status" : 200}'); + return; + // Don't use the connection here, it has been returned to the pool. + }); + }); + }); + + + }); + +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js new file mode 100644 index 000000000..511f4ccb0 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); + +router.post('/', function(req, res) { + console.log(req.body); + req.checkBody("tag_name", "TAG Name must not be empty").notEmpty(); + + var errors = req.validationErrors(); + console.log(errors); + + var response = ''; for(var i = 0; i < errors.length; i++) { + console.log(errors[i]['msg']); + response = response + errors[i]['msg'] + '; '; + } + + if(errors) { res.status(500); + res.send({'error': response}); + return; + } + + var tag_details = req.body; + + db_pool.getConnection(function(err, connection) { + // Use the connection + sql_query = 'INSERT INTO tag SET ?' + connection.query(sql_query, tag_details, function (error, results, fields) { + // And done with the connection. + res.end('{"success" : "Updated Successfully", "status" : 200}'); + return; + connection.release(); + // Handle error after the release. + if (error) throw error; + // Don't use the connection here, it has been returned to the pool. + }); + }); + + + res.end('{"success" : "Updated Successfully", "status" : 200}'); + return; + +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js new file mode 100644 index 000000000..be0664276 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); + +router.get('/', function(req, res) { + var tags = req.param('tags'); + console.log(tags); + res.render('project_profile', { title: 'Express' }); +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js index 49fceeb3c..96f68db7a 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js @@ -9,11 +9,86 @@ var express = require('express'); var router = express.Router(); +var async = require('async'); + + +var renderer = function(res, err, results) { + console.log(results); + res.render('search_projects', { title: 'Express', json: results }); +} + +var get_tags = function(result, callback) { + db_pool.getConnection(function(err, connection) { + sql_query = 'select tag_name from tag where tag_id in (select tag_id from vnf_tags where vnf_id = ' + result['vnf_id'] + ') limit 5'; + // TODO find why it works and not above + connection.query(sql_query, function (error, results, fields) { + console.log(results); + result['tags'] = results; + callback(null, result); + //connection.release(); + if (error) throw error; + }); + }); +} + + +var get_images = function(result, callback) { + db_pool.getConnection(function(err, connection) { + sql_query = 'select photo_url from photo where photo_id = ' + result['photo_id']; + // TODO find why it works here and not when declared outside the method + console.log(sql_query); + connection.query(sql_query, function (error, results, fields) { + console.log(results[0].photo_url); + result['photo_url'] = results[0].photo_url; + callback(null, result); + //connection.release(); + if (error) throw error; + }); + }); +} + +var sql_data = function(tags, renderer, res) { + var tag_array = "\'" + tags.map(function (item) { return item; }).join("\',\'") + "\'"; + console.log(tag_array); + var condition = ''; + db_pool.getConnection(function(err, connection) { + sql_query = 'select tag_id from tag where tag_name in (' + tag_array + ')'; + connection.query(sql_query, function (error, results, fields) { + condition = 'SELECT * FROM vnf as v'; + for (var i in results) { + condition += (i == 0) ? ' WHERE ' : ' AND '; + condition += 'v.vnf_id IN (SELECT vnf_id from vnf_tags where tag_id = ' + results[i]['tag_id'] + ')'; + } + + connection.query(condition, function (error, results, fields) { + console.log(results); + async.map(results, get_images, function(error, results) { + async.map(results, get_tags, renderer.bind(null, res)); + }); + //connection.release(); + if (error) throw error; + }); + + connection.release(); + if (error) throw error; + }); + }); + +} router.get('/', function(req, res) { + + console.log(typeof(req.param('tags'))); var tags = req.param('tags'); - console.log(tags); - res.render('search_projects', { title: 'Express' }); + + if(tags) { + tags = tags.toLowerCase().split(/[ ,]+/); + console.log(tags); + sql_data(tags, renderer, res); + } else { + res.render('search_projects', { title: 'Express', json: false}); + } + }); module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js new file mode 100644 index 000000000..cbe8caefd --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); + +/* Post Controller for Tag autocomplete form */ +router.get('/', function(req, res) { + tag_partial = req.param('key'); + db_pool.getConnection(function(err, connection) { + + sql_query = 'select tag_name from tag where tag_name like "%'+ tag_partial + '%" limit 5'; + // TODO find why it works and not above + connection.query(sql_query, function (error, results, fields) { + console.log(results); + + var data=[]; + for(i = 0; i < results.length; i++) { + data.push(results[i].tag_name.replace(/\r?\n|\r/g, '')); + } + console.log(results); + connection.release(); + res.end(JSON.stringify(results)); + + if (error) throw error; + }); + }); +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js new file mode 100644 index 000000000..a5cf09ca7 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); + +/* Post Controller for Search Vnf autocomplete form */ +router.get('/', function(req, res) { + tag_partial = req.param('key'); + db_pool.getConnection(function(err, connection) { + + sql_query = 'select vnf_name from vnf where vnf_name like "%'+ tag_partial + '%" limit 5'; + // TODO find why it works and not above + connection.query(sql_query, function (error, results, fields) { + console.log(results); + + var data=[]; + for(i = 0; i < results.length; i++) { + data.push(results[i].vnf_name.replace(/\r?\n|\r/g, '')); + } + console.log(results); + connection.release(); + res.end(JSON.stringify(results)); + + if (error) throw error; + }); + }); +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js new file mode 100644 index 000000000..d1a3d726e --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var express = require('express'); +var router = express.Router(); + +/* Post controller for VNF_TAG Association */ +router.post('/', function(req, res) { + req.checkBody("tag_name", "TAG Name must not be empty").notEmpty(); + req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty(); + + var errors = req.validationErrors(); + console.log(errors); + + var response = ''; for(var i = 0; i < errors.length; i++) { + console.log(errors[i]['msg']); + response = response + errors[i]['msg'] + '; '; + } + + if(errors) { res.status(500); + res.send({'error': response}); + return; + } + + var tag_name = req.param('tag_name'); + var vnf_name = req.param('vnf_name'); + + db_pool.getConnection(function(err, connection) { + // Use the connection + //sql_query = 'INSERT INTO tag SET ?' + sql_query = 'insert into vnf_tags(vnf_id, tag_id) values ((select vnf_id from vnf where vnf_name = \'' + vnf_name + '\'), (select tag_id from tag where tag_name = \'' + tag_name + '\'))'; + console.log(sql_query); + connection.query(sql_query, function (error, results, fields) { + // And done with the connection. + + connection.release(); + res.end('{"success" : "Updated Successfully", "status" : 200}'); + + // Handle error after the release. + if (error) throw error; + // Don't use the connection here, it has been returned to the pool. + }); + }); + + res.end('{"success" : "Updated Successfully", "status" : 200}'); + //res.render('vnf_tag_association', { title: 'Express' }); +}); + +module.exports = router; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade new file mode 100644 index 000000000..dde8cfe75 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade @@ -0,0 +1,164 @@ + +.search-box + script(src='/3rd_party/typeahead.js') + script(type='text/javascript', src='/javascripts/mode_edit.js') + .fixed-action-btn.fixed-action-btn_custom + a.btn-floating.btn-large.red + i.large.material-icons mode_edit + ul + li + a.btn-floating.red.tooltipped(href='#modal2', data-position='left', data-delay='50', data-tooltip='Add a TAG') + i.large.material-icons attach_file + li + a.btn-floating.green.tooltipped(href='#modal1', data-position='left', data-delay='50', data-tooltip='Add a VNF') + i.large.material-icons add + li + a.btn-floating.blue.tooltipped(href='#modal3', data-position='left', data-delay='50', data-tooltip='Add a TAG to a VNF') + i.large.material-icons share + #modal1.modal + .modal-content + h4.center + i.material-icons library_add + | Add a VNF + .row + form#add_project_form.col.s12(action='/add_project', enctype='multipart/form-data', method='post') + .row.modal-form-row + .input-field.col.s12 + input#vnf_name.validate(type='text', name='vnf_name') + label.left-align(for='vnf_name') Name + .row + .input-field.col.s12 + input#repo_url.validate(type='text', name='repo_url') + label.left-align(for='repo_url') Github URL + .row + .input-field.col.s12 + select#license + option(value='', name='license', disabled='', selected='') Choose the License + option(value='MIT') MIT + option(value='GPL') GPL + option(value='GPL_V2') GPL_V2 + option(value='BSD') BSD + option(value='APACHE') APACHE + label License + .row + .input-field.col.s12 + select#opnfv_indicator + option(value='', name='opnfv_indicator', disabled='', selected='') Choose the OPNFV Indicator + option(value='silver') silver + option(value='gold') gold + option(value='platinum') platinum + label OPNFV Indicator + + .row + .file-field.input-field + .btn + span Photo (Optional) + input#file_upload(type='file', name='file_upload') + .file-path-wrapper + input.file-path.validate(type='text', name='file_url') + + .row + .input-field.col.s12 + input#submitter_id.validate(type='hidden', name='submitter_id', value=1) + + .row + button#add_project_button.modal-action.modal-close.waves-effect.waves-light.btn.right + | Submit VNF + i.material-icons.right send + #modal2.modal + .modal-content + h4.center + i.material-icons library_add + | Add a TAG + .row + form#add_tag_form.col.s12(action='/add_tag', method='post') + .row.modal-form-row + .input-field.col.s12 + input#tag_name.validate(type='text', name='tag_name') + label.left-align(for='tag_name') Name + button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right + | Submit TAG + i.material-icons.right send + #modal3.modal + h4.center + i.material-icons library_add + | Add a TAG to a VNF + .row + form#add_vnf_tag_association_form.col.s12(action='/vnf_tag_association', method='post') + + .row.modal-form-row.modal-form-row-custom + .input-field.col.s2 VNF Name + #scrollable-dropdown-menu.input-field.col.s4 + input#vnf_name.typeahead(type='text', name='vnf_name') + // + label.left-align(for='tag_name') VNF Name + .input-field.col.s2 TAG Name + #scrollable-dropdown-menu.input-field.col.s4 + input#tag_name.validate.typeahead(type='text', name='tag_name') + // + label.left-align(for='tag_name') TAG Name + + button#add_vnf_tag_association_button.modal-action.modal-close.waves-effect.waves-light.btn.right + | Submit + i.material-icons.right send + style. + .select-dropdown{ + overflow-y: auto !important; + } + .dropdown-content { + max-height: 200px !important; + } + .backdrop{ + background-color: rgb(253,225,109); + } + .bg { + } + .modal-form-row-custom { + min-height: 200px !important; + } + #scrollable-dropdown-menu .tt-menu { + max-height: 150px; + overflow-y: auto; + } + + .typeahead, .tt-query, .tt-hint { + border: 2px solid #CCCCCC; + border-radius: 8px 8px 8px 8px; + font-size: 24px; + height: 30px; + line-height: 30px; + outline: medium none; + padding: 8px 12px; + width: 396px; + } + + .tt-query { + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; + } + .tt-hint { + color: #999999; + } + .tt-dropdown-menu { + background-color: #FFFFFF; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 8px 8px 8px 8px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + margin-top: 12px; + padding: 8px 0; + width: 200px; + } + .tt-suggestion { + font-size: 18px; + line-height: 24px; + padding: 3px 20px; + } + .tt-suggestion.tt-cursor { + background-color: #0097CF; + color: #FFFFFF; + } + .tt-suggestion p { + margin: 0; + } + .tt-dropdown-menu, .gist { + text-align: left; + } diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade index e60c3ba26..bf0cd149e 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade @@ -7,10 +7,11 @@ extends layout which accompanies this distribution, and is available at http://www.apache.org/licenses/LICENSE-2.0 block content + link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css') .search-box h1 VNF Catalogue form.search-form - input.search-input(type='text', placeholder='Search...', id='Tags') + input.search-input(type='search', placeholder='Search...', id='Tags') .space-10 button.search-button(type='submit', value='Search', id='Search') Search .content.content-height-overwrite diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade index 89142f813..33c09e338 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade @@ -9,7 +9,6 @@ html(lang='en') html head title= title - link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css') link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css') script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js') script(src='/javascripts/global.js') @@ -49,5 +48,7 @@ html a(href='#') Sign up li.signin a(href='#') Sign in + block search + block add_project block content diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade new file mode 100644 index 000000000..7b37bd423 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade @@ -0,0 +1,84 @@ +extends layout + +// + Copyright (c) 2017 Kumar Rishabh and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +block search + include search +block content + .content + .container.container-custom + .carousel + a.carousel-item(href='#one!') + img(src='http://lorempixel.com/250/250/nature/1') + a.carousel-item(href='#two!') + img(src='http://lorempixel.com/250/250/nature/2') + a.carousel-item(href='#three!') + img(src='http://lorempixel.com/250/250/nature/3') + a.carousel-item(href='#four!') + img(src='http://lorempixel.com/250/250/nature/4') + a.carousel-item(href='#five!') + img(src='http://lorempixel.com/250/250/nature/5') + .card.card-shadow-custom.horizontal + .row.row-custom + .col.s5.card-title-div-custom + span.card-title.card-title-span-custom Card Title + .col.s5.card-title-div-custom + i.material-icons grade + span.card-title PenguinScore: 42 + .col.s2.card-title-div-custom-right + form(action='#') + input#search_result_1(type='checkbox') + label(for='search_result_1') Compare + // + <div class="card-action"> + <a href="#">This is a link</a> + </div> + .col.s4.card-image.card-image-custom + img.card-image-picture-custom(src='/images/logo.png') + .col.s8.card-stacked + .card-content + p + .collection.collection-custom + a.collection-item(href='#!') + span + i.material-icons code + | Lines Of Code: 1.03M + a.collection-item(href='#!') + span + i.material-icons code + | Lines Of Code: 1.03M + a.collection-item(href='#!') + span + i.material-icons code + | Lines Of Code: 1.03M + a.collection-item(href='#!') + span + i.material-icons code + | Lines Of Code: 1.03M + .card-action + | Tags: + .chip + a.a-custom(href='#!') Tag1 + .chip + a.a-custom(href='#!') Tag2 + .chip + a.a-custom(href='#!') Tag3 + .chip + a.a-custom(href='#!') Tag4 + .chip + a.a-custom(href='#!') Tag5 + a.a-custom-more(href='#!') more + .divider + .card-action-custom.col.s12.card-action + | License: + a(href='#') MIT + | Complexity: + a(href='#') Atomic + footer + | © 2017 XYZ Company + link(rel='stylesheet', href='/stylesheets/search_projects.css') + diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade new file mode 100644 index 000000000..77b24881e --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade @@ -0,0 +1,5 @@ +.search-box + link(rel='stylesheet', href='/stylesheets/search_form.css') + .form-group-custom.form-group.has-feedback + input.search-input-rest.form-control(type='search', placeholder='Search...', id='Tags') + i.material-icons search
\ No newline at end of file diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade index 6670d212c..ac91aa68d 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade @@ -6,70 +6,78 @@ extends layout are made available under the terms of the Apache License, Version 2.0 which accompanies this distribution, and is available at http://www.apache.org/licenses/LICENSE-2.0 +block search + include search +block add_project + include add_project block content - .search-box - .form-group-custom.form-group.has-feedback - input.search-input-rest.form-control(type='text', placeholder='Search...', id='Tags') - i.material-icons search .content - .container - .card.card-shadow-custom.horizontal - .row.row-custom - .col.s5.card-title-div-custom - span.card-title.card-title-span-custom Card Title - .col.s5.card-title-div-custom - i.material-icons grade - span.card-title PenguinScore: 42 - .col.s2.card-title-div-custom-right - form(action='#') - input#search_result_1(type='checkbox') - label(for='search_result_1') Compare - // - <div class="card-action"> - <a href="#">This is a link</a> - </div> - .col.s4.card-image - img.card-image-picture-custom(src='/images/logo.png') - .col.s8.card-stacked - .card-content - p - .collection.collection-custom - a.collection-item(href='#!') - span - i.material-icons code - | Lines Of Code: 1.03M - a.collection-item(href='#!') - span - i.material-icons code - | Lines Of Code: 1.03M - a.collection-item(href='#!') - span - i.material-icons code - | Lines Of Code: 1.03M - a.collection-item(href='#!') - span - i.material-icons code - | Lines Of Code: 1.03M - .card-action - | Tags: - .chip - a.a-custom(href='#!') Tag1 - .chip - a.a-custom(href='#!') Tag2 - .chip - a.a-custom(href='#!') Tag3 - .chip - a.a-custom(href='#!') Tag4 - .chip - a.a-custom(href='#!') Tag5 - a.a-custom-more(href='#!') more - .divider - .card-action-custom.col.s12.card-action - | License: - a(href='#') MIT - | Complexity: - a(href='#') Atomic + each key, index in json + .container.container-custom + .card.card-shadow-custom.horizontal + .row.row-custom + .col.s5.card-title-div-custom + span.card-title.card-title-span-custom #{key.vnf_name} + .col.s5.card-title-div-custom + i.material-icons grade + span.card-title PenguinScore: 42 + .col.s2.card-title-div-custom-right + form(action='#') + input#search_result_1(type='checkbox', name='#{key.vnf_name}') + label(for='search_result_1') Compare + // + <div class="card-action"> + <a href="#">This is a link</a> + </div> + .col.s4.card-image.card-image-custom + img.card-image-picture-custom(src='/uploads/#{key.photo_url}') + .col.s8.card-stacked + .card-content + p + .collection.collection-custom + a.collection-item(href='#!') + span + i.material-icons code + | Lines Of Code: #{key.lines_of_code} + a.collection-item(href='#!') + span + i.material-icons person + | Number of Developers: #{key.no_of_developers} + a.collection-item(href='#!') + span + i.material-icons star + | Number of Stars: #{key.no_of_stars} + a.collection-item(href='#!') + span + i.material-icons description + | Number of Versions: #{key.versions} + .card-action + | Tags: + each tag, index in key.tags + .chip + a.a-custom(href='/search_projects?tags=#{tag.tag_name}') #{tag.tag_name} + // + .chip + a.a-custom(href='#!') tag1 + .chip + a.a-custom(href='#!') Tag2 + .chip + a.a-custom(href='#!') Tag3 + .chip + a.a-custom(href='#!') Tag4 + .chip + a.a-custom(href='#!') Tag5 + a.a-custom-more(href='#!') more + .divider + .card-action-custom.col.s12.card-action + | License: + a(href='#') #{key.license} + | Complexity: + a(href='#') Atomic + | Activity: + a(href='#') Medium + | OPNFV Indicator: + a(href='#') #{key.opnfv_indicator} footer | © 2017 XYZ Company link(rel='stylesheet', href='/stylesheets/search_projects.css') - diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade new file mode 100644 index 000000000..c2e11601d --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade @@ -0,0 +1,167 @@ +doctype html +// + Copyright (c) 2017 Kumar Rishabh and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +html(lang='en') +html + head + title= title + // + link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css') + script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js') + // + script(src='/javascripts/global.js') + // + script(src='/3rd_party/materialize/js/materialize.js') + link(href='https://fonts.googleapis.com/icon?family=Material+Icons', rel='stylesheet') + link(rel='stylesheet', href='/stylesheets/style.css') + script(src='/3rd_party/typeahead.js') + script(src='/javascripts/mode_edit.js') + body + h4.center + i.material-icons library_add + | Add a TAG to a VNF + .row + form#add_tag_form.col.s12(action='/add_tag', method='post') + .row.modal-form-row + .input-field.col.s6 VNF Name + .input-field.col.s6 TAG Name + .row.modal-form-row + #scrollable-dropdown-menu.input-field.col.s6 + input#tag_name.typeahead(type='text', name='tag_name') + // + label.left-align(for='tag_name') VNF Name + + .input-field.col.s6 + input#tag_name.validate(type='text', name='vnf_name') + // + label.left-align(for='tag_name') TAG Name + .row.modal-form-row + .input-field.col.s6 + .input-field.col.s6 + .row.modal-form-row + button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right + | Submit + i.material-icons.right send +style. + #scrollable-dropdown-menu .tt-menu { + max-height: 150px; + overflow-y: auto; + } + + .typeahead, .tt-query, .tt-hint { + border: 2px solid #CCCCCC; + border-radius: 8px 8px 8px 8px; + font-size: 24px; + height: 30px; + line-height: 30px; + outline: medium none; + padding: 8px 12px; + width: 396px; + } + .typeahead { + background-color: #FFFFFF; + } + .typeahead:focus { + border: 2px solid #0097CF; + } + .tt-query { + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; + } + .tt-hint { + color: #999999; + } + .tt-dropdown-menu { + background-color: #FFFFFF; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 8px 8px 8px 8px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + margin-top: 12px; + padding: 8px 0; + width: 422px; + } + .tt-suggestion { + font-size: 18px; + line-height: 24px; + padding: 3px 20px; + } + .tt-suggestion.tt-cursor { + background-color: #0097CF; + color: #FFFFFF; + } + .tt-suggestion p { + margin: 0; + } + .tt-dropdown-menu, .gist { + text-align: left; + } + /* + html { + overflow-y: scroll; + } + .container { + margin: 0 auto; + max-width: 750px; + text-align: center; + } + + html { + color: #333333; + font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 18px; + line-height: 1.2; + } + .title, .example-name { + font-family: Prociono; + } + p { + margin: 0 0 10px; + } + .title { + font-size: 64px; + margin: 20px 0 0; + } + .example { + padding: 30px 0; + } + .example-name { + font-size: 32px; + margin: 20px 0; + } + .demo { + margin: 50px 0; + position: relative; + } + */ + /* + .gist { + font-size: 14px; + } + .example-twitter-oss .tt-suggestion { + padding: 8px 20px; + } + .example-twitter-oss .tt-suggestion + .tt-suggestion { + border-top: 1px solid #CCCCCC; + } + .example-twitter-oss .repo-language { + float: right; + font-style: italic; + } + .example-twitter-oss .repo-name { + font-weight: bold; + } + .example-twitter-oss .repo-description { + font-size: 14px; + } + .example-sports .league-name { + border-bottom: 1px solid #CCCCCC; + margin: 0 20px 5px; + padding: 3px 0; + } + .example-arabic .tt-dropdown-menu { + text-align: right; + } + */ diff --git a/utils/test/vnfcatalogue/cronjobs/README.md b/utils/test/vnfcatalogue/cronjobs/README.md new file mode 100644 index 000000000..cf27ff8c7 --- /dev/null +++ b/utils/test/vnfcatalogue/cronjobs/README.md @@ -0,0 +1,24 @@ +# CRONJOB Directory + +## Helper to setup cronjob to fill the vnf table + +There are two important parameters that need to be set in github.js +before running cronjob. + + +``` + access_token : generate an access token from github account for accessing + the github apis. This is necessary as the non access token limit tends to + be 50 api calls per hour. + delta : the threshold between the last update of the row of the vnf table + and current time. It is measured in seconds. +``` + +Enter the details namely username and password in the **database.js**. +Then setup the cronjob by putting the following line in the crontab + +In the crontab + +```bash + node github +``` diff --git a/utils/test/vnfcatalogue/cronjobs/database.js b/utils/test/vnfcatalogue/cronjobs/database.js new file mode 100644 index 000000000..a1d926e44 --- /dev/null +++ b/utils/test/vnfcatalogue/cronjobs/database.js @@ -0,0 +1,14 @@ +var mysql = require('mysql'); + +var pool = mysql.createPool({ + host: 'localhost', + user: 'myuser', + password: 'mypassword', + database: 'vnf_catalogue', + connectionLimit: 50, + supportBigNumbers: true, + multipleStatements: true, + dateStrings: 'date' +}); + +exports.pool = pool; diff --git a/utils/test/vnfcatalogue/cronjobs/github.js b/utils/test/vnfcatalogue/cronjobs/github.js new file mode 100644 index 000000000..05cc6c155 --- /dev/null +++ b/utils/test/vnfcatalogue/cronjobs/github.js @@ -0,0 +1,129 @@ +// Important Add your access token here default rate of github is limited to 60 API calls per hour +var access_token = '*'; +// Important set the delta threshold for repo details updation. For instance if the threshold is +// set to 1 day(60 * 60 * 24), the cronjob will only update the row if the difference between current +// time and last_updated time stamp of a repo is greater than one day +var delta = 60 * 60 * 24; + + +var github = require('octonode'); +db_pool = require('./database').pool; +async = require('async'); + +var current_time = Math.floor(new Date().getTime() / 1000);//toISOString().slice(0, 19).replace('T', ' '); +console.log(current_time); + +var get_val_from_header = function(header_link) { + // small hack by parsing the header and setting per_page = 1, hence no pagination fetch required + result_intermediate = header_link.split(';'); + result_intermediate = result_intermediate[result_intermediate.length - 2]; + var reg = /&page=([0-9].*)>/g; + var match = reg.exec(result_intermediate); + return parseInt(match[1]); +} + +var get_stargazers = function(result, ghrepo, primary_callback, cb) { + ghrepo.stargazers({per_page: 1}, function(err, data, headers) { + //console.log(JSON.stringify(data)); + try { + result['no_of_stars'] = get_val_from_header(headers['link']); + cb(null, result, ghrepo, primary_callback); + } catch(err) { + result['no_of_stars'] = null; + cb(null, result, ghrepo, primary_callback); + } + }); +} + +var get_branches = function(result, ghrepo, primary_callback, cb) { + ghrepo.branches({per_page: 1}, function(err, data, headers) { + try { + result['versions'] = get_val_from_header(headers['link']); + cb(null, result, ghrepo, primary_callback); + } catch(err) { + result['versions'] = null; + cb(null, result, ghrepo, primary_callback); + } + }); +} + +var get_contributors = function(result, ghrepo, primary_callback, cb) { + ghrepo.contributors({per_page: 1}, function(err, data, headers) { + try { + result['no_of_developers'] = get_val_from_header(headers['link']); + cb(null, result, primary_callback); + } catch(err) { + result['no_of_developers'] = null; + cb(null, result, primary_callback); + + } + }); +} + +var get_lines_of_code = function(result, cb) { + // #TODO +} + +var secondary_callback = function (err, result, primary_callback) { + console.log(result); + if((result['last_updated'] == null) || (current_time - result['last_updated'] > delta)) { + db_pool.getConnection(function(err, connection) { + //Use the connection + var last_updated = current_time; + var no_of_stars = result['no_of_stars']; + var versions = result['versions']; + var no_of_developers = result['no_of_developers']; + sql_query = 'update vnf set last_updated = FROM_UNIXTIME(' + last_updated; + sql_query += '), no_of_stars = ' + no_of_stars + ', versions = ' + versions; + sql_query += ', no_of_developers = ' + no_of_developers + ' where vnf_id = '; + sql_query += result['vnf_id']; + console.log(sql_query); + connection.query(sql_query, function (error, results, fields) { + if (error) throw error; + //And done with the connection. + primary_callback(null, result['vnf_id'] + ' updated'); + connection.release(); + // Handle error after the release. + // Don't use the connection here, it has been returned to the pool. + }); + }); + } else { + primary_callback(null, result['vnf_id'] + ' not updated'); + } +} + +var get_stats = function(vnf_details, callback) { + repo = vnf_details['repo_url']; + repo = repo.split("/"); + github_id = repo[repo.length - 2] + '/' + repo[repo.length - 1]; + + var async = require('async'); + var client = github.client(access_token); + var ghrepo = client.repo(github_id); + + result = {} + result['vnf_id'] = vnf_details['vnf_id']; + result['last_updated'] = vnf_details['last_updated']; + + async.waterfall([ + async.apply(get_stargazers, result, ghrepo, callback), + get_branches, + get_contributors, + //get_lines_of_code, + ], secondary_callback); +} + +db_pool.getConnection(function(err, connection) { + sql_query = 'select vnf_id, repo_url, UNIX_TIMESTAMP(last_updated) last_updated from vnf'; + console.log(sql_query); + connection.query(sql_query, function (error, results, fields) { + if (error) throw error; + async.map(results, get_stats, function(error, results) { + //console.log(results); + console.log(results); + process.exit(); + + }); + }); +}); + diff --git a/utils/test/vnfcatalogue/helpers/migrate.js b/utils/test/vnfcatalogue/helpers/migrate.js index ec209053c..d884d9c68 100644 --- a/utils/test/vnfcatalogue/helpers/migrate.js +++ b/utils/test/vnfcatalogue/helpers/migrate.js @@ -11,8 +11,8 @@ var knex = require('knex')({ client: 'mysql', connection: { host : 'localhost', - user : '*', - password : '*', + user : 'myuser', + password : 'mypassword', database : 'vnf_catalogue', charset : 'utf8' } @@ -28,6 +28,14 @@ function createTable(tableName) { if (Schema[tableName][key].type === 'text' && Schema[tableName][key].hasOwnProperty('fieldtype')) { column = table[Schema[tableName][key].type](key, Schema[tableName][key].fieldtype); } + else if (Schema[tableName][key].type === 'enum' && Schema[tableName][key].hasOwnProperty('values') && Schema[tableName][key].nullable === true) { + console.log(Schema[tableName][key].values); + column = table[Schema[tableName][key].type](key, Schema[tableName][key].values).nullable(); + } + else if (Schema[tableName][key].type === 'enum' && Schema[tableName][key].hasOwnProperty('values')) { + console.log(Schema[tableName][key].values); + column = table[Schema[tableName][key].type](key, Schema[tableName][key].values).notNullable(); + } else if (Schema[tableName][key].type === 'string' && Schema[tableName][key].hasOwnProperty('maxlength')) { column = table[Schema[tableName][key].type](key, Schema[tableName][key].maxlength); } diff --git a/utils/test/vnfcatalogue/helpers/schema.js b/utils/test/vnfcatalogue/helpers/schema.js index 2aaf99ae2..4a7559ad0 100644 --- a/utils/test/vnfcatalogue/helpers/schema.js +++ b/utils/test/vnfcatalogue/helpers/schema.js @@ -31,10 +31,16 @@ var Schema = { lines_of_code: {type: 'integer', nullable: true, unsigned: true}, versions: {type: 'integer', nullable: true, unsigned: true}, no_of_developers: {type: 'integer', nullable: true, unsigned: true}, + no_of_stars: {type: 'integer', nullable: true, unsigned: true}, + license: {type: 'enum', nullable: false, values: ['MIT', 'GPL', 'GPL_V2', 'BSD', 'APACHE']}, + opnfv_indicator: {type: 'enum', nullable: false, values: ['gold', 'silver', 'platinum']}, + complexity: {type: 'enum', nullable: true, values: ['low', 'medium', 'high']}, + activity: {type: 'enum', nullable: true, values: ['low', 'medium', 'high']}, + last_updated: {type: 'dateTime', nullable: true}, }, tag: { tag_id: {type: 'increments', nullable: false, primary: true}, - name: {type: 'string', maxlength: 150, nullable: false} + tag_name: {type: 'string', maxlength: 150, nullable: false} }, vnf_tags: { vnf_tag_id: {type: 'increments', nullable: false, primary: true}, |