FROM maven:3-jdk-8
+RUN apt-get update && apt-get install -y sendmail
WORKDIR /opt/sch
ADD . /opt/sch
# TODO: This is bogus. This is simply to be used for Registrator registration.
EXPOSE 65000
-CMD ["java", "-jar", "/opt/sch/target/dcae-service-change-handler.jar", "prod", "http://consul:8500/v1/kv/service-change-handler?raw=true"]
+COPY startSCH.sh /opt/sch
+RUN chmod +x /opt/sch/startSCH.sh
+CMD ["/opt/sch/startSCH.sh"]
--- /dev/null
+<configuration debug="true" scan="true" scanPeriod="30 seconds">
+
+ <property name="LOG_DIR" value="logs" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <appender name="metricsAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>DEBUG</level>
+ <onMatch>ACCEPT</onMatch>
+ <onMismatch>DENY</onMismatch>
+ </filter>
+ <file>${LOG_DIR}/metrics.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern>${LOG_DIR}/metrics-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <!-- each file should be at most 100MB, keep 2 days worth of history, but at most 200MB -->
+ <maxFileSize>100MB</maxFileSize>
+ <maxHistory>2</maxHistory>
+ <totalSizeCap>200MB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00}|%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00.00}|NULL|UNKONWN|%thread||service-change-handler||||COMPLETE|0|OK||%level||||||%class||||%method|%line|||%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>DEBUG</level>
+ </filter>
+ <file>${LOG_DIR}/debug.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern>${LOG_DIR}/debug-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <!-- each file should be at most 100MB, keep 2 days worth of history, but at most 200MB -->
+ <maxFileSize>100MB</maxFileSize>
+ <maxHistory>2</maxHistory>
+ <totalSizeCap>200MB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00.00}|NULL|%thread:%level:%class:%method:%line:%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="auditAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>INFO</level>
+ <onMatch>ACCEPT</onMatch>
+ <onMismatch>DENY</onMismatch>
+ </filter>
+ <file>${LOG_DIR}/audit.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${LOG_DIR}/audit-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <maxFileSize>100MB</maxFileSize>
+ <maxHistory>2</maxHistory>
+ <totalSizeCap>200MB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00}|%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00}|NULL|UNKNOWN|%thread||service-change-handler||COMPLETE|0|OK||%level||||||%class|||%method|%line|||%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>ERROR</level>
+ </filter>
+ <file>${LOG_DIR}/error.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern>${LOG_DIR}/error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <!-- each file should be at most 100MB, keep 2 days worth of history, but at most 200MB -->
+ <maxFileSize>100MB</maxFileSize>
+ <maxHistory>2</maxHistory>
+ <totalSizeCap>200MB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00.00}|NULL|%thread|service-change-handler||||%level|500|ERROR|%class:%method:%line:%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="metricsLogger" level="info" additivity="false">
+ <appender-ref ref="metricsAppender" />
+ </logger>
+
+ <logger name="debugLogger" level="debug" additivity="false">
+ <appender-ref ref="debugAppender" />
+ </logger>
+
+ <logger name="auditLogger" level="info" additivity="false">
+ <appender-ref ref="auditAppender" />
+ </logger> -->
+
+ <logger name="errorLogger" level="error" additivity="false">
+ <appender-ref ref="errorAppender" />
+ </logger>
+
+ <root level="debug">
+ <appender-ref ref="metricsAppender" />
+ <appender-ref ref="debugAppender" />
+ <appender-ref ref="auditAppender" />
+ <appender-ref ref="errorAppender" />
+ </root>
+
+</configuration>
<artifactId>cheshire</artifactId>
<version>5.8.0</version>
</dependency>
+ <dependency>
+ <groupId>com.draines</groupId>
+ <artifactId>postal</artifactId>
+ <version>2.0.2</version>
+ </dependency>
<dependency>
<groupId>org.onap.sdc.sdc-distribution-client</groupId>
<artifactId>sdc-distribution-client</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
- <groupId>com.taoensso</groupId>
- <artifactId>timbre</artifactId>
- <version>4.10.0</version>
- </dependency>
- <!-- Does magic so traditional Java loggers show up -->
- <dependency>
- <groupId>com.fzakaria</groupId>
- <artifactId>slf4j-timbre</artifactId>
- <version>0.3.8</version>
+ <groupId>org.clojure</groupId>
+ <artifactId>tools.logging</artifactId>
+ <version>0.4.0</version>
</dependency>
<dependency>
<groupId>clj-http</groupId>
<artifactId>clj-yaml</artifactId>
<version>0.4.0</version>
</dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.2.1</version>
+ </dependency>
<dependency>
<groupId>clj-fakes</groupId>
<artifactId>clj-fakes</artifactId>
:description "Service change handler"
:dependencies [[org.clojure/clojure "1.8.0"]
[cheshire/cheshire "5.8.0"]
- [com.taoensso/timbre "4.7.4"]
- [com.fzakaria/slf4j-timbre "0.3.2"]
+ [org.clojure/tools.logging "0.4.0"]
[clj-http/clj-http "3.3.0"]
[org.bovinegenius/exploding-fish "0.3.4"]
[clj-yaml/clj-yaml "0.4.0"]
[org.onap.sdc.sdc-distribution-client/sdc-distribution-client "1.3.0"]
+ [ch.qos.logback/logback-classic "1.2.1"]
]
; TODO: Fill in the onap maven repository info
(ns sch.asdc-client
(:require [clj-http.client :as client]
- [taoensso.timbre :as timbre :refer [error]]
+ [clojure.tools.logging :as logger :refer [debug error]]
[cheshire.core :refer [parse-string]]
[org.bovinegenius.exploding-fish :refer [uri param]])
(:gen-class))
(defn get-artifact!
[connection artifact-path]
+ (debug (str "Entering get-artifact - artiface-path:" artifact-path))
(let [[asdc-uri user password instance-id insecure?] connection
target-uri (assoc asdc-uri :path artifact-path)
resp (client/get (str target-uri) { :basic-auth [user password]
(defn get-service-metadata!
[connection service-uuid]
+ (debug (str "Entering get-service-metadta - service-uuid:" service-uuid))
(let [[asdc-uri user password instance-id insecure?] connection
target-uri (assoc asdc-uri :path (construct-service-path service-uuid))
resp (client/get (str target-uri) { :basic-auth [user password]
(ns sch.core
(:require [clojure.java.io :refer :all]
[cheshire.core :refer [parse-stream parse-string]]
- [taoensso.timbre :as timbre :refer [info error]]
- [taoensso.timbre.appenders.3rd-party.rolling :refer [rolling-appender]]
+ [clojure.tools.logging :as logger :refer [debug info error]]
[sch.handle :refer [handle-change-event! download-artifacts! deploy-artifacts!
deployed-ok deployed-error deployed-already]]
[sch.asdc-client :refer [get-service-metadata! create-asdc-conn get-consumer-id]]
[sch.parse :refer [get-dcae-artifact-types pick-out-artifact]]
[sch.util :refer [read-config]]
[clojure.string :as strlib]
+ [postal.core :refer [send-message]]
)
(:import (org.onap.sdc.impl DistributionClientFactory)
(org.onap.sdc.api.consumer IConfiguration INotificationCallback
- IDistributionStatusMessage)
+ IDistributionStatusMessage IComponentDoneStatusMessage)
(org.onap.sdc.utils DistributionActionResultEnum DistributionStatusEnum)
(com.google.gson Gson)
)
(str (.getDistributionMessageResult resp)))))
))
+(defn send-component-done-status!
+ "Convenience function used to send component done status messages"
+ [dist-client distribution-id consumer-id msg artifact status]
+ (let [dist-message (proxy [IComponentDoneStatusMessage] []
+ (getDistributionID [] distribution-id)
+ (getConsumerID [] consumer-id)
+ (getTimestamp []
+ (. java.lang.System currentTimeMillis))
+ (getArtifactURL [] (:artifactURL artifact))
+ (getComponentName [] "service-change-handler")
+ (getStatus [] status))
+ resp (if (strlib/blank? msg)
+ (.sendComponentDoneStatus dist-client dist-message)
+ (.sendComponentDoneStatus dist-client dist-message "failed to deploy to inventory"))
+ ]
+ (if (not= (.getDistributionActionResult resp) (. DistributionActionResultEnum SUCCESS))
+ (error (str "Problem sending status: " (:artifactName artifact) ", "
+ (str (.getDistributionMessageResult resp)))))
+ ))
+
(defn deploy-artifacts-ex!
"Enhanced deploy artifacts function
After calling deploy-artifacts!, this method takes the results and sends out
appropriate distribution status messages per artifact processed"
- [inventory-uri service-metadata requests send-dist-status]
+ [inventory-uri service-metadata requests send-dist-status send-comp-done-status fromEmail toEmail]
(let [[to-post posted to-delete deleted] (deploy-artifacts! inventory-uri service-metadata
requests)
pick-out-artifact (partial pick-out-artifact service-metadata)]
- (dorun (map #(send-dist-status (pick-out-artifact %)
+ (dorun (map #(do
+ (send-dist-status (pick-out-artifact %)
(. DistributionStatusEnum DEPLOY_OK))
+ (send-comp-done-status "" (pick-out-artifact %)
+ (. DistributionStatusEnum COMPONENT_DONE_OK))
+ (if (and (not (strlib/blank? fromEmail)) (not (strlib/blank? toEmail)))
+ (do
+ (debug (str "Sending notification from " fromEmail " to " toEmail))
+ (try
+ (send-message {:from fromEmail
+ :to [toEmail]
+ :subject "DCAE inventory blueprint downloaded from ASDC and inserted into inventory DB"
+ :body (str
+ "ASDC blueprint has been inserted into inventory <"
+ inventory-uri
+ ">.\n"
+ (pick-out-artifact %)
+ )
+ })
+ (catch Exception e (error (str "caught exception from send-message" (.getMessage e))))
+ )
+ )
+ )
+ )
(deployed-ok to-post posted)))
- (dorun (map #(send-dist-status (pick-out-artifact %)
+ (dorun (map #(do
+ (send-dist-status (pick-out-artifact %)
(. DistributionStatusEnum DEPLOY_ERROR))
+ (send-comp-done-status "failed to deploy to inventory" (pick-out-artifact %)
+ (. DistributionStatusEnum COMPONENT_DONE_ERROR))
+ )
(deployed-error to-post posted)))
- (dorun (map #(send-dist-status (pick-out-artifact %)
+ (dorun (map #(do
+ (send-dist-status (pick-out-artifact %)
(. DistributionStatusEnum ALREADY_DEPLOYED))
+ (send-comp-done-status "" (pick-out-artifact %)
+ (. DistributionStatusEnum COMPONENT_DONE_OK))
+ )
(deployed-already requests to-post)))
; REVIEW: How about the deleted service types?
))
(getKeyStorePassword [] (str (:keyStorePassword config-asdc)))
(activateServerTLSAuth [] (boolean (:activateServerTLSAuth config-asdc)))
(isFilterInEmptyResources [] (boolean (:isFilterInEmptyResources config-asdc)))
- (isUseHttpsWithDmaap [] (boolean (:useHttpsWithDmaap config-asdc false)))
+ (isUseHttpsWithDmaap [] (boolean (:useHttpsWithDmaap config-asdc true)))
(isConsumeProduceStatusTopic [] (boolean (:isConsumeProduceStatusTopic config-asdc false)))
)))
Uses the asdc distribution client and to poll for notification events and makes calls
to handle those events"
- [dist-client-config inventory-uri asdc-conn]
+ [dist-client-config inventory-uri asdc-conn fromEmail toEmail]
+ (debug "Entering run-distribution-client")
(let [dist-client (. DistributionClientFactory createDistributionClient)
dist-client-callback (proxy [INotificationCallback] []
(activateCallback [data]
Discovered that the notification event and the service metadata
data models are different. Use service metadata because its
richer."
+ (debug "Entering dist-client-callback")
(let [change-event (parse-string (.toJson (Gson.) data) true)
service-id (:serviceUUID change-event)
distribution-id (:distributionID change-event)
send-dist-status (partial send-distribution-status!
dist-client distribution-id
(get-consumer-id asdc-conn))
+ send-comp-done-status (partial send-component-done-status!
+ dist-client distribution-id
+ (get-consumer-id asdc-conn))
]
(info (str "Handle change event: " (:serviceName change-event)
% (. DistributionStatusEnum DOWNLOAD_OK))
artifacts))
(deploy-artifacts-ex! inventory-uri service-metadata
- requests send-dist-status)
+ requests send-dist-status send-comp-done-status
+ fromEmail toEmail)
)
)))
(error dist-client-init-result))
)))
-(defn- setup-logging-rolling
- "Setup logging with the rolling appender"
- [{ {:keys [currentLogFilename rotationFrequency]} :logging }]
- (let [rolling-params (when currentLogFilename { :path currentLogFilename })
- rolling-params (when rotationFrequency
- (assoc rolling-params :pattern (keyword rotationFrequency)))]
- (timbre/merge-config! { :level :debug :appenders { :rolling (rolling-appender rolling-params) } })
- (info "Setup logging: Rolling appender" (if rolling-params rolling-params "DEFAULT"))
- ))
-
-
(defn -main [& args]
(let [[mode config-path event-path] args
config (read-config config-path)
inventory-uri (create-inventory-conn config)
asdc-conn (create-asdc-conn config)
+ fromEmail (get-in config [:notification :fromEmail])
+ toEmail (get-in config [:notification :toEmail])
]
- (setup-logging-rolling config)
-
+ (if (and (not (strlib/blank? fromEmail)) (not (strlib/blank? toEmail)))
+ (debug "Email notification enabled")
+ )
(if (= "DEV" (clojure.string/upper-case mode))
(do
(info "Development mode")
)
(run-distribution-client!
(create-distribution-client-config config)
- inventory-uri asdc-conn)
+ inventory-uri asdc-conn fromEmail toEmail)
)
(info "Done"))
(ns sch.handle
(:require [clojure.java.io :refer :all]
- [taoensso.timbre :as timbre :refer [info error]]
+ [clojure.tools.logging :as logger :refer [info error]]
[sch.inventory-client :refer [get-service-types! post-service-type!
delete-service-type!]]
[sch.asdc-client :refer [get-artifact!]]
(ns sch.inventory-client
(:require [clj-http.client :as client]
- [taoensso.timbre :as timbre :refer [error]]
+ [clojure.tools.logging :as logger :refer [error]]
[cheshire.core :refer [parse-string]]
[org.bovinegenius.exploding-fish :refer [uri param]])
(:gen-class))
(ns sch.parse
(:require [clojure.java.io :refer :all]
- [taoensso.timbre :as timbre :refer [info error]]
+ [clojure.tools.logging :as logger]
[sch.asdc-client :refer [construct-service-path]]
[cheshire.core :refer [parse-string]]
)
--- /dev/null
+#!/bin/bash
+
+grep "^nameserver" /opt/sch/etc/resolv.conf >> /etc/resolv.conf
+
+service sendmail start
+
+java -Dlogback.configurationFile=logback.xml -jar /opt/sch/target/dcae-service-change-handler.jar prod http://consul:8500/v1/kv/service-change-handler?raw=true
+
(send-dist-status-only-ok [artifact status]
(if (not= (. DistributionStatusEnum ALREADY_DEPLOYED) status)
(throw (Exception. "Distribution status should be ALREADY DEPLOYED"))
+ ))
+ (send-comp-done-status-only-ok [msg artifact status]
+ (if (not= (. DistributionStatusEnum COMPONENT_DONE_OK) status)
+ (throw (Exception. "Distribution status should be COMPONENT DONE OK"))
))]
(let [service-metadata [{:resources [{:resourceInvariantUUID "123"
:artifacts [:artifactName "type-foo"]
(f/with-fakes
(f/patch! #'sch.handle/deploy-artifacts! deploy-artifacts)
(is (= nil (deploy-artifacts-ex! "http://inventory" service-metadata requests
- send-dist-status-only-ok))))
+ send-dist-status-only-ok send-comp-done-status-only-ok "" ""))))
)))
major=1\r
-minor=1\r
-patch=5\r
+minor=2\r
+patch=0\r
base_version=${major}.${minor}.${patch}\r
release_version=${base_version}\r
snapshot_version=${base_version}-SNAPSHOT\r