| #!/bin/bash |
| # ================================================================================ |
| # Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. |
| # ================================================================================ |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # ============LICENSE_END========================================================= |
| |
| set -e |
| |
| CDAP_HOST='localhost' |
| CDAP_PORT='11015' |
| TCA_NAMESPACE='cdap_tca_hi_lo' |
| TCA_APPNAME='dcae-tca' |
| |
| TCA_ARTIFACT='dcae-analytics-cdap-tca' |
| TCA_FILE_PATH='/opt/tca' |
| TCA_JAR="$(ls -1r ${TCA_FILE_PATH}/${TCA_ARTIFACT}*.jar | head -1)" |
| TCA_ARTIFACT_VERSION=$(echo "$TCA_JAR" |rev |cut -f 2-4 -d '.' |rev) |
| TCA_APP_CONF="${TCA_FILE_PATH}/tca_app_config.json" |
| TCA_CONF="${TCA_FILE_PATH}/tca_config.json" |
| TCA_PREF="${TCA_FILE_PATH}/tca_app_preferences.json" |
| TCA_CONF_TEMP='/tmp/tca_config.json' |
| TCA_APP_CONF_TEMP='/tmp/tca_app_config.json' |
| TCA_PREF_TEMP='/tmp/tca_preferences.json' |
| |
| TCA_PATH_APP="${CDAP_HOST}:${CDAP_PORT}/v3/namespaces/${TCA_NAMESPACE}/apps/${TCA_APPNAME}" |
| TCA_PATH_ARTIFACT="${CDAP_HOST}:${CDAP_PORT}/v3/namespaces/${TCA_NAMESPACE}/artifacts" |
| |
| MR_WATCHDOG_PATH="${TCA_FILE_PATH}/mr-watchdog.sh" |
| |
| |
| WORKER_COUNT='0' |
| |
| # Remove consul dependency for CBS lookup (DCAEGEN2-2021) |
| # CBS Host and port are set to CBS K8S service name and port identified on CBS deployment via Helm |
| CBS_HOST=${CBS_HOST:-config-binding-service} |
| CBS_PORT=${CBS_PORT:-10000} |
| |
| #CONSUL_HOST=${CONSUL_HOST:-consul} |
| #CONSUL_PORT=${CONSUL_PORT:-8500} |
| #CONFIG_BINDING_SERVICE=${CONFIG_BINDING_SERVICE:-config_binding_service} |
| CBS_SERVICE_NAME=${CBS_SERVICE_NAME:-config_binding_service} |
| |
| #Changing to HOSTNAME parameter for consistency with k8s deploy |
| MY_NAME=${HOSTNAME:-tca} |
| |
| |
| echo "Generting preference file" |
| DMAAPSUBGROUP=${DMAAPSUBGROUP:-OpenDCAEc12} |
| DMAAPSUBID=${DMAAPSUBID:=c12} |
| sed -i 's/{{DMAAPHOST}}/'"${DMAAPHOST}"'/g' ${TCA_PREF} |
| sed -i 's/{{DMAAPPORT}}/'"${DMAAPPORT}"'/g' ${TCA_PREF} |
| sed -i 's/{{DMAAPPUBTOPIC}}/'"${DMAAPPUBTOPIC}"'/g' ${TCA_PREF} |
| sed -i 's/{{DMAAPSUBTOPIC}}/'"${DMAAPSUBTOPIC}"'/g' ${TCA_PREF} |
| sed -i 's/{{DMAAPSUBGROUP}}/'"${DMAAPSUBGROUP}"'/g' ${TCA_PREF} |
| sed -i 's/{{DMAAPSUBID}}/'"${DMAAPSUBID}"'/g' ${TCA_PREF} |
| sed -i 's/{{AAIHOST}}/'"${AAIHOST}"'/g' ${TCA_PREF} |
| sed -i 's/{{AAIPORT}}/'"${AAIPORT}"'/g' ${TCA_PREF} |
| if [ -z "$REDISHOSTPORT" ]; then |
| sed -i 's/{{REDISHOSTPORT}}/NONE/g' ${TCA_PREF} |
| sed -i 's/{{REDISCACHING}}/false/g' ${TCA_PREF} |
| else |
| sed -i 's/{{REDISHOSTPORT}}/'"${REDISHOSTPORT}"'/g' ${TCA_PREF} |
| sed -i 's/{{REDISCACHING}}/true/g' ${TCA_PREF} |
| fi |
| |
| function tca_stop { |
| # stop programs |
| echo |
| echo "Stopping TCADMaaPMRPublisherWorker, TCADMaaPMRSubscriberWorker, and TCAVESCollectorFlow ..." |
| echo |
| curl -s -X POST "http://${TCA_PATH_APP}/workers/TCADMaaPMRPublisherWorker/stop" |
| curl -s -X POST "http://${TCA_PATH_APP}/workers/TCADMaaPMRSubscriberWorker/stop" |
| curl -s -X POST "http://${TCA_PATH_APP}/flows/TCAVESCollectorFlow/stop" |
| echo "done" |
| echo |
| } |
| |
| function tca_load_artifact { |
| echo |
| echo "Loading artifact ${TCA_JAR} to http://${TCA_PATH_ARTIFACT}/${TCA_ARTIFACT}..." |
| curl -s -X POST --data-binary @"${TCA_JAR}" "http://${TCA_PATH_ARTIFACT}/${TCA_ARTIFACT}" |
| echo |
| } |
| |
| function tca_load_conf { |
| echo |
| echo "Loading configuration ${TCA_APP_CONF} to http://${TCA_PATH_APP}" |
| curl -s -X PUT -d @${TCA_APP_CONF} http://${TCA_PATH_APP} |
| echo |
| |
| # load preferences |
| echo |
| echo "Loading preferences ${TCA_PREF} to http://${TCA_PATH_APP}/preferences" |
| curl -s -X PUT -d @${TCA_PREF} http://${TCA_PATH_APP}/preferences |
| echo |
| } |
| |
| |
| function tca_delete { |
| echo |
| echo "Deleting application dcae-tca http://${TCA_PATH_APP}" |
| curl -s -X DELETE http://${TCA_PATH_APP} |
| echo |
| |
| # delete artifact |
| echo |
| echo "Deleting artifact http://${TCA_PATH_ARTIFACT}/${TCA_ARTIFACT}/versions/${TCA_ARTIFACT_VERSION} ..." |
| curl -s -X DELETE "http://${TCA_PATH_ARTIFACT}/${TCA_ARTIFACT}/versions/${TCA_ARTIFACT_VERSION}" |
| echo |
| } |
| |
| function tca_start { |
| echo |
| echo "Starting TCADMaaPMRPublisherWorker, TCADMaaPMRSubscriberWorker, and TCAVESCollectorFlow ..." |
| curl -s -X POST "http://${TCA_PATH_APP}/workers/TCADMaaPMRPublisherWorker/start" |
| curl -s -X POST "http://${TCA_PATH_APP}/workers/TCADMaaPMRSubscriberWorker/start" |
| curl -s -X POST "http://${TCA_PATH_APP}/flows/TCAVESCollectorFlow/start" |
| echo |
| } |
| |
| |
| function tca_status { |
| WORKER_COUNT='0' |
| echo |
| STATUS=$(curl -s "http://${TCA_PATH_APP}/workers/TCADMaaPMRPublisherWorker/status") |
| echo "TCADMaaPMRPublisherWorker status: $STATUS" |
| INC=$(echo "$STATUS" | jq . |grep RUNNING |wc -l) |
| WORKER_COUNT=$((WORKER_COUNT+INC)) |
| |
| STATUS=$(curl -s "http://${TCA_PATH_APP}/workers/TCADMaaPMRSubscriberWorker/status") |
| echo "TCADMaaPMRSubscriberWorker status: $STATUS" |
| INC=$(echo "$STATUS" | jq . |grep RUNNING |wc -l) |
| WORKER_COUNT=$((WORKER_COUNT+INC)) |
| |
| STATUS=$(curl -s "http://${TCA_PATH_APP}/flows/TCAVESCollectorFlow/status") |
| echo "TCAVESCollectorFlow status: $STATUS" |
| INC=$(echo "$STATUS" | jq . |grep RUNNING |wc -l) |
| WORKER_COUNT=$((WORKER_COUNT+INC)) |
| echo |
| } |
| |
| |
| function tca_restart { |
| MR_HOST=$(jq .subscriberHostName ${TCA_PREF} |sed -e 's/\"//g') |
| MR_PORT=$(jq .subscriberHostPort ${TCA_PREF} |sed -e 's/\"//g') |
| MR_TOPIC=$(jq .subscriberTopicName ${TCA_PREF} |sed -e 's/\"//g') |
| echo "Verifying DMaaP topic: ${MR_TOPIC}@${MR_HOST}:${MR_PORT} (will block until topic ready)" |
| "${MR_WATCHDOG_PATH}" "${MR_HOST}" "${MR_PORT}" "${MR_TOPIC}" |
| tca_stop |
| tca_delete |
| tca_load_artifact |
| tca_load_conf |
| tca_start |
| sleep 5 |
| tca_status |
| } |
| |
| function tca_poll_policy { |
| URL0="${CBS_HOST}:${CBS_PORT}/service_component_all/${MY_NAME}" |
| echo "tca_poll_policy: Retrieving all-in-one config at ${URL0}" |
| HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" "$URL0") |
| HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') |
| HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') |
| |
| if [ "$HTTP_STATUS" != "200" ]; then |
| echo "tca_poll_policy: Retrieving all-in-one config failed with status $HTTP_STATUS" |
| URL1="${CBS_HOST}:${CBS_PORT}/service_component/${MY_NAME}" |
| echo "tca_poll_policy: Retrieving app config only at ${URL1}" |
| HTTP_RESPONSE1=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" "$URL1") |
| HTTP_BODY1=$(echo "$HTTP_RESPONSE1" | sed -e 's/HTTPSTATUS\:.*//g') |
| HTTP_STATUS1=$(echo "$HTTP_RESPONSE1" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') |
| if [ "$HTTP_STATUS1" != "200" ]; then |
| echo "tca_poll_policy: Retrieving app config only failed with status $HTTP_STATUS1" |
| return |
| fi |
| |
| URL2="$URL1:preferences" |
| echo "tca_poll_policy: Retrieving app preferences only at ${URL2}" |
| HTTP_RESPONSE2=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" "$URL2") |
| HTTP_BODY2=$(echo "$HTTP_RESPONSE2" | sed -e 's/HTTPSTATUS\:.*//g') |
| HTTP_STATUS2=$(echo "$HTTP_RESPONSE2" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') |
| if [ "$HTTP_STATUS2" != "200" ]; then |
| echo "tca_poll_policy: Retrieving app preferences only failed with status $HTTP_STATUS2" |
| return |
| fi |
| |
| if [[ "$CONFIG" == "null" || "$PREF" == "null" ]]; then |
| echo "tca_poll_policy: either app config or app preferences being empty, config not applicable" |
| return |
| fi |
| |
| echo "$HTTP_BODY1" | jq . --sort-keys > "${TCA_CONF_TEMP}" |
| echo "$HTTP_BODY2" | jq . --sort-keys > "${TCA_PREF_TEMP}" |
| else |
| CONFIG=$(echo "$HTTP_BODY" | jq .config.app_config) |
| PREF=$(echo "$HTTP_BODY" | jq .config.app_preferences) |
| POLICY=$(echo "$HTTP_BODY" | jq .policies.items[0].config.tca_policy) |
| |
| |
| if [[ "$CONFIG" == "null" || "$PREF" == "null" ]]; then |
| echo "tca_poll_policy: CONFIG received is parsed to be empty, trying to parse using R1 format" |
| CONFIG=$(echo "$HTTP_BODY" | jq .config) |
| NEWPREF=$(echo "$HTTP_BODY" | jq .preferences) |
| |
| #echo "CONFIG is [$CONFIG]" |
| #echo "NEWPREF is [$NEWPREF]" |
| else |
| echo "tca_poll_policy: CONFIG is [${CONFIG}], PREF is [${PREF}], POLICY is [${POLICY}]" |
| ## Check if policy content under tca_policy is returned null |
| ## null indicates no active policy flow; hence use configuration loaded |
| ## from blueprint |
| if [ "$POLICY" == "null" ]; then |
| # tca_policy through blueprint |
| NEWPREF=${PREF} |
| else |
| # tca_policy through active policy flow through PH |
| NEWPREF=$(echo "$PREF" | jq --arg tca_policy "$POLICY" '. + {$tca_policy}') |
| fi |
| NEWPREF=$(echo "$NEWPREF" | sed 's/\\n//g') |
| fi |
| |
| if [[ "$CONFIG" == "null" || "$NEWPREF" == "null" ]]; then |
| echo "tca_poll_policy: either app config or app preferences being empty, config not applicable" |
| return |
| fi |
| |
| echo "$CONFIG" | jq . --sort-keys > "${TCA_CONF_TEMP}" |
| echo "$NEWPREF" | jq . --sort-keys > "${TCA_PREF_TEMP}" |
| fi |
| |
| if [ ! -e "${TCA_CONF_TEMP}" ] || [ "$(ls -sh ${TCA_CONF_TEMP} |cut -f1 -d' ' |sed -e 's/[^0-9]//g')" -lt "1" ]; then |
| echo "Fail to receive configuration" |
| return |
| fi |
| if [ ! -e "${TCA_PREF_TEMP}" ] || [ "$(ls -sh ${TCA_PREF_TEMP} |cut -f1 -d' ' |sed -e 's/[^0-9]//g')" -lt "1" ]; then |
| echo "Fail to receive preferences" |
| return |
| fi |
| |
| CONF_CHANGED="" |
| # extract only the config section from APP CONF (which has both artifact and config sections) |
| jq .config --sort-keys ${TCA_APP_CONF} > ${TCA_CONF} |
| if ! diff ${TCA_CONF} ${TCA_CONF_TEMP} ; then |
| echo "TCA config changed" |
| # generating the new app conf using current app conf's artifact section and the new downloaded config |
| jq --argfile CONFVALUE ${TCA_CONF_TEMP} '.config = $CONFVALUE' <${TCA_APP_CONF} > ${TCA_APP_CONF_TEMP} |
| |
| mv ${TCA_APP_CONF_TEMP} ${TCA_APP_CONF} |
| CONF_CHANGED=1 |
| fi |
| |
| PERF_CHANGED="" |
| # update the subscriber ConsumerID, if not already unique, |
| # so replicas appear as different consumers in the consumer group |
| HOSTID=$(head -1 /etc/hostname | rev |cut -f1-2 -d'-' |rev) |
| CONSUMERID=$(jq .subscriberConsumerId ${TCA_PREF_TEMP} |sed -e 's/\"//g') |
| if ! (echo "$CONSUMERID" |grep "$HOSTID"); then |
| CONSUMERID="${CONSUMERID}-${HOSTID}" |
| jq --arg CID "${CONSUMERID}" '.subscriberConsumerId = $CID' < "${TCA_PREF_TEMP}" > "${TCA_PREF_TEMP}2" |
| mv "${TCA_PREF_TEMP}2" "${TCA_PREF_TEMP}" |
| fi |
| if ! diff ${TCA_PREF} ${TCA_PREF_TEMP} ; then |
| echo "TCA preference updated" |
| mv ${TCA_PREF_TEMP} ${TCA_PREF} |
| PERF_CHANGED=1 |
| fi |
| |
| if [[ "$PERF_CHANGED" == "1" || "$CONF_CHANGED" == "1" ]]; then |
| echo "Newly received configuration/preference differ from the running instance's. reload confg" |
| tca_restart |
| else |
| echo "Newly received configuration/preference identical from the running instance's" |
| fi |
| } |
| |
| |
| export PATH=${PATH}:/opt/cdap/sdk/bin |
| |
| |
| echo "Starting TCA-CDAP in standalone mode" |
| |
| # starting CDAP SDK in background |
| cdap sdk start |
| |
| echo "CDAP Started, waiting CDAP ready on ${CDAP_HOST}:${CDAP_PORT} ..." |
| while ! nc -z ${CDAP_HOST} ${CDAP_PORT}; do |
| sleep 1 # wait for 1 second before check again |
| done |
| |
| echo "Creating namespace cdap_tca_hi_lo ..." |
| curl -s -X PUT "http://${CDAP_HOST}:${CDAP_PORT}/v3/namespaces/cdap_tca_hi_lo" |
| |
| # stop programs |
| tca_stop |
| # delete application |
| tca_delete |
| # load artifact |
| tca_load_artifact |
| tca_load_conf |
| # start programs |
| tca_start |
| |
| # get status of programs |
| tca_status |
| |
| echo "TCA-CDAP standalone mode initialization completed, with $WORKER_COUNT / 3 up" |
| |
| |
| |
| #Changing to HOSTNAME parameter for consistency with k8s deploy |
| MY_NAME=${HOSTNAME:-tca} |
| |
| echo "TCA environment: I am ${MY_NAME}, CBS K8S Service Name and port is ${CBS_HOST}:${CBS_PORT}" |
| |
| while echo |
| do |
| echo "======================================================> $(date)" |
| tca_status |
| |
| while [ "$WORKER_COUNT" != "3" ]; do |
| echo "Status checking: worker count is $WORKER_COUNT, needs a reset" |
| sleep 5 |
| |
| tca_restart |
| echo "TCA restarted" |
| done |
| |
| |
| #Below commented to remove consul lookup and use k8s servicename for CBS (DCAEGEN2-2021) |
| # if [[ -z "$CBS_HOST" || -z "$CBS_PORT" ]]; then |
| # echo "Retrieving host and port for ${CBS_SERVICE_NAME} from ${CONSUL_HOST}:${CONSUL_PORT}" |
| # sleep 2 |
| # CBS_HOST=$(curl -s "${CONSUL_HOST}:${CONSUL_PORT}/v1/catalog/service/${CBS_SERVICE_NAME}" |jq .[0].ServiceAddress |sed -e 's/\"//g') |
| # CBS_PORT=$(curl -s "${CONSUL_HOST}:${CONSUL_PORT}/v1/catalog/service/${CBS_SERVICE_NAME}" |jq .[0].ServicePort |sed -e 's/\"//g') |
| # echo "CBS discovered to be at ${CBS_HOST}:${CBS_PORT}" |
| # fi |
| |
| if [ ! -z "$CBS_HOST" ] && [ ! -z "$CBS_PORT" ]; then |
| tca_poll_policy |
| fi |
| sleep 30 |
| done |