diff --git a/docs/STORM-UI-REST-API.md b/docs/STORM-UI-REST-API.md index bbed956b58c..1832da562cc 100644 --- a/docs/STORM-UI-REST-API.md +++ b/docs/STORM-UI-REST-API.md @@ -46,8 +46,8 @@ are used by nimbus. Examples: ```no-highlight - 1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1425844354\?doAsUser=testUSer1 - 2. curl 'http://localhost:8080/api/v1/topology/wordcount-1-1425844354/activate' -X POST -H 'doAsUser:testUSer1' + 1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount\?doAsUser=testUSer1 + 2. curl 'http://localhost:8080/api/v1/topology/wordcount/activate' -X POST -H 'doAsUser:testUSer1' ``` ## GET Operations @@ -264,7 +264,7 @@ Sample response: ### /api/v1/topology-workers/:id (GET) -Returns the worker' information (host and port) for a topology. +Returns the worker' information (host and port) for a topology. id can be name or id of the topology Response fields: @@ -297,13 +297,13 @@ Sample response: ### /api/v1/topology/:id (GET) -Returns topology information and statistics. Substitute id with topology id. +Returns topology information and statistics. Substitute id with topology id or name. Request parameters: |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |window |String. Default value :all-time| Window duration for metrics in seconds| |sys |String. Values 1 or 0. Default value 0| Controls including sys stats part of the response| @@ -361,9 +361,9 @@ Response fields: Examples: ```no-highlight - 1. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825 - 2. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825?sys=1 - 3. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825?window=600 + 1. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3 + 2. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3?sys=1 + 3. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3?window=600 ``` Sample response: @@ -517,7 +517,7 @@ Returns detailed metrics and executor information |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |component |String (required)| Component Id | |window |String. Default value :all-time| window duration for metrics in seconds| |sys |String. Values 1 or 0. Default value 0| controls including sys stats part of the response| @@ -563,9 +563,9 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825/component/spout -2. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825/component/spout?sys=1 -3. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3-1-1402960825/component/spout?window=600 +1. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3/component/spout +2. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3/component/spout?sys=1 +3. http://ui-daemon-host-name:8080/api/v1/topology/WordCount3/component/spout?window=600 ``` Sample response: @@ -731,7 +731,7 @@ Request to start profiler on worker with timeout. Returns status and link to pro |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | |timeout |String (required)| Time out for profiler to stop in minutes | @@ -747,9 +747,9 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/start/10.11.1.7:6701/10 -2. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/start/10.11.1.7:6701/5 -3. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/start/10.11.1.7:6701/20 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/start/10.11.1.7:6701/10 +2. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/start/10.11.1.7:6701/5 +3. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/start/10.11.1.7:6701/20 ``` Sample response: @@ -769,7 +769,7 @@ Request to dump profiler recording on worker. Returns status and worker id for t |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | Response fields: @@ -782,7 +782,7 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/dumpprofile/10.11.1.7:6701 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/dumpprofile/10.11.1.7:6701 ``` Sample response: @@ -800,7 +800,7 @@ Request to stop profiler on worker. Returns status and worker id for the request |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | Response fields: @@ -813,7 +813,7 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/stop/10.11.1.7:6701 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/stop/10.11.1.7:6701 ``` Sample response: @@ -831,7 +831,7 @@ Request to dump jstack on worker. Returns status and worker id for the request. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | Response fields: @@ -844,7 +844,7 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/dumpjstack/10.11.1.7:6701 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/dumpjstack/10.11.1.7:6701 ``` Sample response: @@ -862,7 +862,7 @@ Request to dump heap (jmap) on worker. Returns status and worker id for the requ |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | Response fields: @@ -875,7 +875,7 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/dumpheap/10.11.1.7:6701 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/dumpheap/10.11.1.7:6701 ``` Sample response: @@ -893,7 +893,7 @@ Request to request the worker. Returns status and worker id for the request. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |host-port |String (required)| Worker Id | Response fields: @@ -906,7 +906,7 @@ Response fields: Examples: ```no-highlight -1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount-1-1446614150/profiling/restartworker/10.11.1.7:6701 +1. http://ui-daemon-host-name:8080/api/v1/topology/wordcount/profiling/restartworker/10.11.1.7:6701 ``` Sample response: @@ -926,7 +926,7 @@ Activates a topology. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | Sample Response: @@ -941,7 +941,7 @@ Deactivates a topology. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | Sample Response: @@ -956,7 +956,7 @@ Rebalances a topology. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |wait-time |String (required)| Wait time before rebalance happens | |rebalanceOptions| Json (optional) | topology rebalance options | @@ -973,7 +973,7 @@ Examples: curl -i -b ~/cookiejar.txt -c ~/cookiejar.txt -X POST -H "Content-Type: application/json" -d '{"rebalanceOptions": {"numWorkers": 2, "executors": { "spout" : "5", "split": 7, "count": 5 }}, "callback":"foo"}' -http://localhost:8080/api/v1/topology/wordcount-1-1420308665/rebalance/0 +http://localhost:8080/api/v1/topology/wordcount/rebalance/0 ``` Sample Response: @@ -990,7 +990,7 @@ Kills a topology. |Parameter |Value |Description | |----------|--------|-------------| -|id |String (required)| Topology Id | +|id |String (required)| Topology Id or Name | |wait-time |String (required)| Wait time before rebalance happens | Caution: Small wait times (0-5 seconds) may increase the probability of triggering the bug reported in diff --git a/storm-core/src/clj/org/apache/storm/ui/core.clj b/storm-core/src/clj/org/apache/storm/ui/core.clj index 885d754f2f6..710c1153c32 100644 --- a/storm-core/src/clj/org/apache/storm/ui/core.clj +++ b/storm-core/src/clj/org/apache/storm/ui/core.clj @@ -39,7 +39,7 @@ ExecutorAggregateStats SpecificAggregateStats ComponentPageInfo LogConfig LogLevel LogLevelAction]) (:import [org.apache.storm.security.auth AuthUtils ReqContext]) - (:import [org.apache.storm.generated AuthorizationException ProfileRequest ProfileAction NodeInfo]) + (:import [org.apache.storm.generated AuthorizationException ProfileRequest ProfileAction NodeInfo NotAliveException]) (:import [org.apache.storm.security.auth AuthUtils]) (:import [org.apache.storm.utils Utils VersionInfo ConfigUtils]) (:import [org.apache.storm Config]) @@ -485,6 +485,21 @@ "assignedCpu" (.get_assigned_cpu t)}) "schedulerDisplayResource" (*STORM-CONF* Config/SCHEDULER_DISPLAY_RESOURCE)})) +(defn get-topology-id [topology-name-or-id] + (let [summary ((all-topologies-summary) "topologies") + filter-fun-name (fn[topo-summary] (= (topo-summary "name") topology-name-or-id)) + filter-fun-id (fn[topo-summary] (= (topo-summary "id") topology-name-or-id)) + matching-topologies-by-name (filter filter-fun-name summary) + matching-topologies-by-id (filter filter-fun-id summary) + matching-topologies + (cond + (not-empty matching-topologies-by-name) matching-topologies-by-name + (not-empty matching-topologies-by-id) matching-topologies-by-id + :else nil) + _ (when (empty? matching-topologies) (throw (NotAliveException. (str topology-name-or-id " is not alive")))) + id ((first matching-topologies) "id")] + id)) + (defn topology-stats [window stats] (let [times (stats-times (:emitted stats)) display-map (into {} (for [t times] [t window-hint])) @@ -976,179 +991,193 @@ (assert-authorized-user "getClusterInfo") (json-response (all-topologies-summary) (:callback m))) (GET "/api/v1/topology-workers/:id" [:as {:keys [cookies servlet-request]} id & m] - (let [id (URLDecoder/decode id)] + (let [id (get-topology-id (URLDecoder/decode id))] (json-response {"hostPortList" (worker-host-port id) "logviewerPort" (*STORM-CONF* LOGVIEWER-PORT)} (:callback m)))) (GET "/api/v1/topology/:id" [:as {:keys [cookies servlet-request scheme]} id & m] (.mark ui:num-topology-page-http-requests) (populate-context! servlet-request) - (assert-authorized-user "getTopology" (topology-config id)) - (let [user (get-user-name servlet-request)] - (json-response (topology-page id (:window m) (check-include-sys? (:sys m)) user (= scheme :https)) (:callback m)))) + (let [id (get-topology-id id)] + (assert-authorized-user "getTopology" (topology-config id)) + (let [user (get-user-name servlet-request)] + (json-response (topology-page id (:window m) (check-include-sys? (:sys m)) user (= scheme :https)) (:callback m))))) (GET "/api/v1/topology/:id/visualization-init" [:as {:keys [cookies servlet-request]} id & m] (.mark ui:num-build-visualization-http-requests) (populate-context! servlet-request) - (assert-authorized-user "getTopology" (topology-config id)) - (json-response (build-visualization id (:window m) (check-include-sys? (:sys m))) (:callback m))) + (let [id (get-topology-id id)] + (assert-authorized-user "getTopology" (topology-config id)) + (json-response (build-visualization id (:window m) (check-include-sys? (:sys m))) (:callback m)))) (GET "/api/v1/topology/:id/visualization" [:as {:keys [cookies servlet-request]} id & m] (.mark ui:num-mk-visualization-data-http-requests) (populate-context! servlet-request) - (assert-authorized-user "getTopology" (topology-config id)) - (json-response (mk-visualization-data id (:window m) (check-include-sys? (:sys m))) (:callback m))) + (let [id (get-topology-id id)] + (assert-authorized-user "getTopology" (topology-config id)) + (json-response (mk-visualization-data id (:window m) (check-include-sys? (:sys m))) (:callback m)))) (GET "/api/v1/topology/:id/component/:component" [:as {:keys [cookies servlet-request scheme]} id component & m] (.mark ui:num-component-page-http-requests) (populate-context! servlet-request) - (assert-authorized-user "getTopology" (topology-config id)) - (let [user (get-user-name servlet-request)] - (json-response - (component-page id component (:window m) (check-include-sys? (:sys m)) user (= scheme :https)) - (:callback m)))) + (let [id (get-topology-id id)] + (assert-authorized-user "getTopology" (topology-config id)) + (let [user (get-user-name servlet-request)] + (json-response + (component-page id component (:window m) (check-include-sys? (:sys m)) user (= scheme :https)) + (:callback m))))) (GET "/api/v1/topology/:id/logconfig" [:as {:keys [cookies servlet-request]} id & m] (.mark ui:num-log-config-http-requests) (populate-context! servlet-request) - (assert-authorized-user "getTopology" (topology-config id)) - (json-response (log-config id) (:callback m))) + (let [id (get-topology-id id)] + (assert-authorized-user "getTopology" (topology-config id)) + (json-response (log-config id) (:callback m)))) + (POST "/api/v1/topology/:id/activate" [:as {:keys [cookies servlet-request]} id & m] (.mark ui:num-activate-topology-http-requests) (populate-context! servlet-request) - (assert-authorized-user "activate" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg)] - (.activate nimbus name) - (log-message "Activating topology '" name "'"))) - (json-response (topology-op-response id "activate") (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "activate" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg)] + (.activate nimbus name) + (log-message "Activating topology '" name "'"))) + (json-response (topology-op-response id "activate") (m "callback")))) (POST "/api/v1/topology/:id/deactivate" [:as {:keys [cookies servlet-request]} id & m] (.mark ui:num-deactivate-topology-http-requests) (populate-context! servlet-request) - (assert-authorized-user "deactivate" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg)] - (.deactivate nimbus name) - (log-message "Deactivating topology '" name "'"))) - (json-response (topology-op-response id "deactivate") (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "deactivate" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg)] + (.deactivate nimbus name) + (log-message "Deactivating topology '" name "'"))) + (json-response (topology-op-response id "deactivate") (m "callback")))) (POST "/api/v1/topology/:id/debug/:action/:spct" [:as {:keys [cookies servlet-request]} id action spct & m] (.mark ui:num-debug-topology-http-requests) (populate-context! servlet-request) - (assert-authorized-user "debug" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg) - enable? (= "enable" action)] - (.debug nimbus name "" enable? (Integer/parseInt spct)) - (log-message "Debug topology [" name "] action [" action "] sampling pct [" spct "]"))) - (json-response (topology-op-response id (str "debug/" action)) (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "debug" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg) + enable? (= "enable" action)] + (.debug nimbus name "" enable? (Integer/parseInt spct)) + (log-message "Debug topology [" name "] action [" action "] sampling pct [" spct "]"))) + (json-response (topology-op-response id (str "debug/" action)) (m "callback")))) (POST "/api/v1/topology/:id/component/:component/debug/:action/:spct" [:as {:keys [cookies servlet-request]} id component action spct & m] (.mark ui:num-component-op-response-http-requests) (populate-context! servlet-request) - (assert-authorized-user "debug" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg) - enable? (= "enable" action)] - (.debug nimbus name component enable? (Integer/parseInt spct)) - (log-message "Debug topology [" name "] component [" component "] action [" action "] sampling pct [" spct "]"))) - (json-response (component-op-response id component (str "/debug/" action)) (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "debug" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg) + enable? (= "enable" action)] + (.debug nimbus name component enable? (Integer/parseInt spct)) + (log-message "Debug topology [" name "] component [" component "] action [" action "] sampling pct [" spct "]"))) + (json-response (component-op-response id component (str "/debug/" action)) (m "callback")))) (POST "/api/v1/topology/:id/rebalance/:wait-time" [:as {:keys [cookies servlet-request]} id wait-time & m] (.mark ui:num-topology-op-response-http-requests) (populate-context! servlet-request) - (assert-authorized-user "rebalance" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg) - rebalance-options (m "rebalanceOptions") - options (RebalanceOptions.)] - (.set_wait_secs options (Integer/parseInt wait-time)) - (if (and (not-nil? rebalance-options) (contains? rebalance-options "numWorkers")) - (.set_num_workers options (Integer/parseInt (.toString (rebalance-options "numWorkers"))))) - (if (and (not-nil? rebalance-options) (contains? rebalance-options "executors")) - (doseq [keyval (rebalance-options "executors")] - (.put_to_num_executors options (key keyval) (Integer/parseInt (.toString (val keyval)))))) - (.rebalance nimbus name options) - (log-message "Rebalancing topology '" name "' with wait time: " wait-time " secs"))) - (json-response (topology-op-response id "rebalance") (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "rebalance" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg) + rebalance-options (m "rebalanceOptions") + options (RebalanceOptions.)] + (.set_wait_secs options (Integer/parseInt wait-time)) + (if (and (not-nil? rebalance-options) (contains? rebalance-options "numWorkers")) + (.set_num_workers options (Integer/parseInt (.toString (rebalance-options "numWorkers"))))) + (if (and (not-nil? rebalance-options) (contains? rebalance-options "executors")) + (doseq [keyval (rebalance-options "executors")] + (.put_to_num_executors options (key keyval) (Integer/parseInt (.toString (val keyval)))))) + (.rebalance nimbus name options) + (log-message "Rebalancing topology '" name "' with wait time: " wait-time " secs"))) + (json-response (topology-op-response id "rebalance") (m "callback")))) (POST "/api/v1/topology/:id/kill/:wait-time" [:as {:keys [cookies servlet-request]} id wait-time & m] (.mark ui:num-topology-op-response-http-requests) (populate-context! servlet-request) - (assert-authorized-user "killTopology" (topology-config id)) - (thrift/with-configured-nimbus-connection nimbus - (let [tplg (->> (doto - (GetInfoOptions.) - (.set_num_err_choice NumErrorsChoice/NONE)) - (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) - name (.get_name tplg) - options (KillOptions.)] - (.set_wait_secs options (Integer/parseInt wait-time)) - (.killTopologyWithOpts nimbus name options) - (log-message "Killing topology '" name "' with wait time: " wait-time " secs"))) - (json-response (topology-op-response id "kill") (m "callback"))) + (let [id (get-topology-id id)] + (assert-authorized-user "killTopology" (topology-config id)) + (thrift/with-configured-nimbus-connection nimbus + (let [tplg (->> (doto + (GetInfoOptions.) + (.set_num_err_choice NumErrorsChoice/NONE)) + (.getTopologyInfoWithOpts ^Nimbus$Client nimbus id)) + name (.get_name tplg) + options (KillOptions.)] + (.set_wait_secs options (Integer/parseInt wait-time)) + (.killTopologyWithOpts nimbus name options) + (log-message "Killing topology '" name "' with wait time: " wait-time " secs"))) + (json-response (topology-op-response id "kill") (m "callback")))) (POST "/api/v1/topology/:id/logconfig" [:as {:keys [cookies servlet-request]} id namedLoggerLevels & m] (.mark ui:num-topology-op-response-http-requests) (populate-context! servlet-request) - (assert-authorized-user "setLogConfig" (topology-config id)) - (thrift/with-configured-nimbus-connection - nimbus - (let [new-log-config (LogConfig.)] - (doseq [[key level] namedLoggerLevels] - (let [logger-name (str key) - target-level (.get level "target_level") - timeout (or (.get level "timeout") 0) - named-logger-level (LogLevel.)] - ;; if target-level is nil, do not set it, user wants to clear - (log-message "The target level for " logger-name " is " target-level) - (if (nil? target-level) - (do - (.set_action named-logger-level LogLevelAction/REMOVE) - (.unset_target_log_level named-logger-level)) - (do - (.set_action named-logger-level LogLevelAction/UPDATE) - ;; the toLevel here ensures the string we get is valid - (.set_target_log_level named-logger-level (.name (Level/toLevel target-level))) - (.set_reset_log_level_timeout_secs named-logger-level timeout))) - (log-message "Adding this " logger-name " " named-logger-level " to " new-log-config) - (.put_to_named_logger_level new-log-config logger-name named-logger-level))) - (log-message "Setting topology " id " log config " new-log-config) - (.setLogConfig nimbus id new-log-config) - (json-response (log-config id) (m "callback"))))) + (let [id (get-topology-id id)] + (assert-authorized-user "setLogConfig" (topology-config id)) + (thrift/with-configured-nimbus-connection + nimbus + (let [new-log-config (LogConfig.)] + (doseq [[key level] namedLoggerLevels] + (let [logger-name (str key) + target-level (.get level "target_level") + timeout (or (.get level "timeout") 0) + named-logger-level (LogLevel.)] + ;; if target-level is nil, do not set it, user wants to clear + (log-message "The target level for " logger-name " is " target-level) + (if (nil? target-level) + (do + (.set_action named-logger-level LogLevelAction/REMOVE) + (.unset_target_log_level named-logger-level)) + (do + (.set_action named-logger-level LogLevelAction/UPDATE) + ;; the toLevel here ensures the string we get is valid + (.set_target_log_level named-logger-level (.name (Level/toLevel target-level))) + (.set_reset_log_level_timeout_secs named-logger-level timeout))) + (log-message "Adding this " logger-name " " named-logger-level " to " new-log-config) + (.put_to_named_logger_level new-log-config logger-name named-logger-level))) + (log-message "Setting topology " id " log config " new-log-config) + (.setLogConfig nimbus id new-log-config) + (json-response (log-config id) (m "callback")))))) (GET "/api/v1/topology/:id/profiling/start/:host-port/:timeout" [:as {:keys [servlet-request]} id host-port timeout & m] (if (get *STORM-CONF* WORKER-PROFILER-ENABLED) (do (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp (+ (System/currentTimeMillis) (* 60000 (Long. timeout))) - request (ProfileRequest. nodeinfo - ProfileAction/JPROFILE_STOP)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port - "timeout" timeout - "dumplink" (worker-dump-link - host - port - id)} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp (+ (System/currentTimeMillis) (* 60000 (Long. timeout))) + request (ProfileRequest. nodeinfo + ProfileAction/JPROFILE_STOP)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port + "timeout" timeout + "dumplink" (worker-dump-link + host + port + id)} + (m "callback")))))) (json-profiling-disabled (m "callback")))) (GET "/api/v1/topology/:id/profiling/stop/:host-port" @@ -1156,18 +1185,19 @@ (if (get *STORM-CONF* WORKER-PROFILER-ENABLED) (do (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp 0 - request (ProfileRequest. nodeinfo - ProfileAction/JPROFILE_STOP)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp 0 + request (ProfileRequest. nodeinfo + ProfileAction/JPROFILE_STOP)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port} + (m "callback")))))) (json-profiling-disabled (m "callback")))) (GET "/api/v1/topology/:id/profiling/dumpprofile/:host-port" @@ -1175,67 +1205,71 @@ (if (get *STORM-CONF* WORKER-PROFILER-ENABLED) (do (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp (System/currentTimeMillis) - request (ProfileRequest. nodeinfo - ProfileAction/JPROFILE_DUMP)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp (System/currentTimeMillis) + request (ProfileRequest. nodeinfo + ProfileAction/JPROFILE_DUMP)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port} + (m "callback")))))) (json-profiling-disabled (m "callback")))) (GET "/api/v1/topology/:id/profiling/dumpjstack/:host-port" [:as {:keys [servlet-request]} id host-port & m] (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp (System/currentTimeMillis) - request (ProfileRequest. nodeinfo - ProfileAction/JSTACK_DUMP)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp (System/currentTimeMillis) + request (ProfileRequest. nodeinfo + ProfileAction/JSTACK_DUMP)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port} + (m "callback")))))) (GET "/api/v1/topology/:id/profiling/restartworker/:host-port" [:as {:keys [servlet-request]} id host-port & m] (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp (System/currentTimeMillis) - request (ProfileRequest. nodeinfo - ProfileAction/JVM_RESTART)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp (System/currentTimeMillis) + request (ProfileRequest. nodeinfo + ProfileAction/JVM_RESTART)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port} + (m "callback")))))) (GET "/api/v1/topology/:id/profiling/dumpheap/:host-port" [:as {:keys [servlet-request]} id host-port & m] (populate-context! servlet-request) - (thrift/with-configured-nimbus-connection nimbus - (assert-authorized-user "setWorkerProfiler" (topology-config id)) - (let [[host, port] (split host-port #":") - nodeinfo (NodeInfo. host (set [(Long. port)])) - timestamp (System/currentTimeMillis) - request (ProfileRequest. nodeinfo - ProfileAction/JMAP_DUMP)] - (.set_time_stamp request timestamp) - (.setWorkerProfiler nimbus id request) - (json-response {"status" "ok" - "id" host-port} - (m "callback"))))) + (let [id (get-topology-id id)] + (thrift/with-configured-nimbus-connection nimbus + (assert-authorized-user "setWorkerProfiler" (topology-config id)) + (let [[host, port] (split host-port #":") + nodeinfo (NodeInfo. host (set [(Long. port)])) + timestamp (System/currentTimeMillis) + request (ProfileRequest. nodeinfo + ProfileAction/JMAP_DUMP)] + (.set_time_stamp request timestamp) + (.setWorkerProfiler nimbus id request) + (json-response {"status" "ok" + "id" host-port} + (m "callback")))))) (GET "/" [:as {cookies :cookies}] (.mark ui:num-main-page-http-requests) diff --git a/storm-core/src/ui/public/component.html b/storm-core/src/ui/public/component.html index 6d5465f17de..129fe0d05b8 100644 --- a/storm-core/src/ui/public/component.html +++ b/storm-core/src/ui/public/component.html @@ -132,12 +132,13 @@

Storm UI

workerActionSelected = {}; $(document).ready(function() { + var topologyId; var componentId = $.url("?id"); - var topologyId = $.url("?topology_id"); - var tableStateKey = ":".concat(topologyId, ":", componentId); + var topologyName = $.url("?topology_name"); + var tableStateKey = ":".concat(topologyName, ":", componentId); var window = $.url("?window"); var sys = $.cookies.get("sys") || "false"; - var url = "/api/v1/topology/"+topologyId+"/component/"+componentId+"?sys="+sys; + var url = "/api/v1/topology/"+topologyName+"/component/"+componentId+"?sys="+sys; if(window) url += "&window="+window; $.extend( $.fn.dataTable.defaults, { @@ -186,6 +187,7 @@

Storm UI

} $.getJSON(url,function(response,status,jqXHR) { + topologyId = response["topologyId"]; var uiUser = $("#ui-user"); $.get("/templates/user-template.html", function(template) { uiUser.append(Mustache.render($(template).filter("#user-template").html(),response)); @@ -194,7 +196,7 @@

Storm UI

var componentSummary = $("#component-summary"); var componentActions = $("#component-actions"); - var buttonJsonData = componentActionJson(response["encodedTopologyId"], response["encodedId"], response["id"], + var buttonJsonData = componentActionJson(response["name"], response["encodedId"], response["id"], response["topologyStatus"], response["debug"], response["samplingPct"]); var componentStatsDetail = $("#component-stats-detail") var inputStats = $("#component-input-stats"); @@ -328,7 +330,7 @@

Storm UI

}); function start_profiling() { - var topologyId = $.url("?topology_id"); + var topologyName = $.url("?topology_name"); var timeout = $("#timeout").val(); if(timeout == "") { timeout = 10; } @@ -340,7 +342,7 @@

Storm UI

var failed = {} var passed = {} Object.keys(workerActionSelected).forEach(function (id) { - var url = "/api/v1/topology/"+topologyId+"/profiling/start/" + id + "/" + timeout; + var url = "/api/v1/topology/"+topologyName+"/profiling/start/" + id + "/" + timeout; $.get(url, function(response,status,jqXHR) { jsError(function() { $.get("/templates/component-page-template.html", function(template) { @@ -376,8 +378,8 @@

Storm UI

} function stop_profiling(id) { - var topologyId = $.url("?topology_id"); - var url = "/api/v1/topology/"+topologyId+"/profiling/stop/" + id; + var topologyName = $.url("?topology_name"); + var url = "/api/v1/topology/"+topologyName+"/profiling/stop/" + id; $("#stop_" + id).prop('disabled', true); setTimeout(function(){ $("#stop_" + id).prop('disabled', false); }, 5000); @@ -392,8 +394,8 @@

Storm UI

} function dump_profile(id) { - var topologyId = $.url("?topology_id"); - var url = "/api/v1/topology/"+topologyId+"/profiling/dumpprofile/" + id; + var topologyName = $.url("?topology_name"); + var url = "/api/v1/topology/"+topologyName+"/profiling/dumpprofile/" + id; $("#dump_profile_" + id).prop('disabled', true); setTimeout(function(){ $("#dump_profile_" + id).prop('disabled', false); }, 5000); @@ -408,12 +410,12 @@

Storm UI

// Create jstack output for all selected workers. function dump_jstacks() { - var topologyId = $.url("?topology_id"); + var topologyName = $.url("?topology_name"); var failed = {} var passed = {} Object.keys(workerActionSelected).forEach(function (id) { - var url = "/api/v1/topology/"+topologyId+"/profiling/dumpjstack/" + id; + var url = "/api/v1/topology/"+topologyName+"/profiling/dumpjstack/" + id; $("#dump_jstack_" + id).prop('disabled', true); setTimeout(function(){ $("#dump_jstack_" + id).prop('disabled', false); }, 5000); @@ -437,8 +439,8 @@

Storm UI

// Create jstack output for the worker with the given id. function dump_jstack(id) { - var topologyId = $.url("?topology_id"); - var url = "/api/v1/topology/"+topologyId+"/profiling/dumpjstack/" + id; + var topologyName = $.url("?topology_name"); + var url = "/api/v1/topology/"+topologyName+"/profiling/dumpjstack/" + id; $("#dump_jstack_" + id).prop('disabled', true); setTimeout(function(){ $("#dump_jstack_" + id).prop('disabled', false); }, 5000); @@ -452,11 +454,11 @@

Storm UI

} function restart_worker_jvms() { - var topologyId = $.url("?topology_id"); + var topologyName = $.url("?topology_name"); var failed = {} var passed = {} Object.keys(workerActionSelected).forEach(function (id) { - var url = "/api/v1/topology/"+topologyId+"/profiling/restartworker/" + id; + var url = "/api/v1/topology/"+topologyName+"/profiling/restartworker/" + id; $("#restart_worker_jvm_" + id).prop('disabled', true); setTimeout(function(){ $("#restart_worker_jvm_" + id).prop('disabled', false); }, 5000); @@ -480,11 +482,11 @@

Storm UI

// Create java heap output for all selected workers. function dump_heaps() { - var topologyId = $.url("?topology_id"); + var topologyName = $.url("?topology_name"); var failed = {} var passed = {} Object.keys(workerActionSelected).forEach(function (id) { - var url = "/api/v1/topology/"+topologyId+"/profiling/dumpheap/" + id; + var url = "/api/v1/topology/"+topologyName+"/profiling/dumpheap/" + id; var heap = $("#dump_heap_" + id); $("#dump_heap_" + id).prop('disabled', true); setTimeout(function(){ $("#dump_heap_" + id).prop('disabled', false); }, 5000); @@ -508,8 +510,8 @@

Storm UI

// Create java heap output for the worker with the given id. function dump_heap(id) { - var topologyId = $.url("?topology_id"); - var url = "/api/v1/topology/"+topologyId+"/profiling/dumpheap/" + id; + var topologyName = $.url("?topology_name"); + var url = "/api/v1/topology/"+topologyName+"/profiling/dumpheap/" + id; var heap = $("#dump_heap_" + id); $("#dump_heap_" + id).prop('disabled', true); setTimeout(function(){ $("#dump_heap_" + id).prop('disabled', false); }, 5000); diff --git a/storm-core/src/ui/public/js/script.js b/storm-core/src/ui/public/js/script.js index a880205a710..a3de6062024 100644 --- a/storm-core/src/ui/public/js/script.js +++ b/storm-core/src/ui/public/js/script.js @@ -81,10 +81,10 @@ function ensureInt(n) { return isInt; } -function sendRequest(id, action, extra, body, cb){ +function sendRequest(name, action, extra, body, cb){ var opts = { type:'POST', - url:'/api/v1/topology/' + id + '/' + action + url:'/api/v1/topology/' + name + '/' + action }; if (body) { @@ -101,10 +101,10 @@ function sendRequest(id, action, extra, body, cb){ }); } -function confirmComponentAction(topologyId, componentId, componentName, action, param, defaultParamValue, paramText, actionText) { +function confirmComponentAction(name, componentId, componentName, action, param, defaultParamValue, paramText, actionText) { var opts = { type:'POST', - url:'/api/v1/topology/' + topologyId + '/component/' + componentId + '/' + action + url:'/api/v1/topology/' + name + '/component/' + componentId + '/' + action }; if (actionText === undefined) { actionText = action; @@ -140,7 +140,7 @@ function confirmComponentAction(topologyId, componentId, componentName, action, function confirmAction(id, name, action, param, defaultParamValue, paramText, actionText) { var opts = { type:'POST', - url:'/api/v1/topology/' + id + '/' + action + url:'/api/v1/topology/' + name + '/' + action }; if (actionText === undefined) { actionText = action; @@ -226,9 +226,9 @@ function topologyActionJson(id, encodedId, name, status, msgTimeout, debug, samp return jsonData; } -function componentActionJson(encodedTopologyId, encodedId, componentName, status, debug, samplingPct) { +function componentActionJson(topologyName, encodedId, componentName, status, debug, samplingPct) { var jsonData = {}; - jsonData["encodedTopologyId"] = encodedTopologyId; + jsonData["topologyName"] = topologyName; jsonData["encodedId"] = encodedId; jsonData["componentName"] = componentName; jsonData["startDebugStatus"] = (status === "ACTIVE" && !debug) ? "enabled" : "disabled"; diff --git a/storm-core/src/ui/public/js/visualization.js b/storm-core/src/ui/public/js/visualization.js index 9aab0875f59..52c527dc48b 100644 --- a/storm-core/src/ui/public/js/visualization.js +++ b/storm-core/src/ui/public/js/visualization.js @@ -387,7 +387,7 @@ function jsError(other) { var should_update; function show_visualization(sys) { - $.getJSON("/api/v1/topology/"+$.url("?id")+"/visualization-init",function(response,status,jqXHR) { + $.getJSON("/api/v1/topology/"+$.url("?name")+"/visualization-init",function(response,status,jqXHR) { $.get("/templates/topology-page-template.html", function(template) { jsError(function() { var topologyVisualization = $("#visualization-container"); @@ -412,7 +412,7 @@ function show_visualization(sys) { var update = function(should_rechoose){ if(should_update) { $.ajax({ - url: "/api/v1/topology/"+$.url("?id")+"/visualization", + url: "/api/v1/topology/"+$.url("?name")+"/visualization", success: function(data, status, jqXHR) { topology_data = data; update_data(topology_data, sys); diff --git a/storm-core/src/ui/public/templates/component-page-template.html b/storm-core/src/ui/public/templates/component-page-template.html index 3626291309d..fb452d4c6dc 100644 --- a/storm-core/src/ui/public/templates/component-page-template.html +++ b/storm-core/src/ui/public/templates/component-page-template.html @@ -49,7 +49,7 @@

Component summary

{{id}} - {{name}} + {{name}} {{executors}} {{tasks}} events @@ -96,7 +96,7 @@

Spout stats

{{#spoutSummary}} - {{windowPretty}} + {{windowPretty}} {{emitted}} {{transferred}} {{completeLatency}} @@ -331,7 +331,7 @@

Bolt stats

{{#boltStats}} - {{windowPretty}} + {{windowPretty}} {{emitted}} {{transferred}} {{executeLatency}} @@ -557,7 +557,9 @@

Errors

diff --git a/storm-core/src/ui/public/templates/index-page-template.html b/storm-core/src/ui/public/templates/index-page-template.html index 0bd66a9491d..5c252e8b93b 100644 --- a/storm-core/src/ui/public/templates/index-page-template.html +++ b/storm-core/src/ui/public/templates/index-page-template.html @@ -171,7 +171,7 @@ {{#topologies}} - {{name}} + {{name}} {{owner}} {{status}} {{uptime}} diff --git a/storm-core/src/ui/public/templates/topology-page-template.html b/storm-core/src/ui/public/templates/topology-page-template.html index 02b3c7693b1..9f3dd7ee43e 100644 --- a/storm-core/src/ui/public/templates/topology-page-template.html +++ b/storm-core/src/ui/public/templates/topology-page-template.html @@ -192,7 +192,7 @@

Topology stats

{{#topologyStats}} - {{windowPretty}} + {{windowPretty}} {{emitted}} {{transferred}} {{completeLatency}} @@ -309,7 +309,7 @@

Spouts ({{windowHint}})

{{#spouts}} -
{{spoutId}} + {{spoutId}} {{executors}} {{tasks}} {{emitted}} @@ -402,7 +402,7 @@

Bolts ({{windowHint}})

{{#bolts}} - {{boltId}} + {{boltId}} {{executors}} {{tasks}} {{emitted}} diff --git a/storm-core/src/ui/public/topology.html b/storm-core/src/ui/public/topology.html index feb81f8f271..5dd5478143e 100644 --- a/storm-core/src/ui/public/topology.html +++ b/storm-core/src/ui/public/topology.html @@ -107,7 +107,7 @@

Topology resources

} function sendLoggerLevel(id){ - var topologyId = $.url("?id"); + var topologyName = $.url("?name"); var shouldRemove = $("#loggerRemove-" + id).val() === "true"; var level = $("#loggerLevel-" + id).val(); var timeout = parseInt($("#loggerTimeout-" + id).val()); @@ -143,11 +143,11 @@

Topology resources

loggerSetting.reset_level = "INFO"; loggerSetting.timeout = timeout; - sendRequest (topologyId, "logconfig", null, data, toggleChangeLogLevel); + sendRequest (topologyName, "logconfig", null, data, toggleChangeLogLevel); }; function renderLogLevelForm (template, responseData){ - var topologyId = $.url("?id"); + var topologyName = $.url("?name"); var container = $("#change-log-level"); var levels = [ @@ -226,8 +226,8 @@

Topology resources

container.show('fast'); }; if (!responseData) { - var topologyId = $.url("?id"); - $.get ('/api/v1/topology/' + topologyId + '/logconfig', renderImpl); + var topologyName = $.url("?name"); + $.get ('/api/v1/topology/' + topologyName + '/logconfig', renderImpl); } else { renderImpl (responseData); } @@ -239,11 +239,11 @@

Topology resources

} }); $(document).ready(function() { - var topologyId = $.url("?id"); - var tableStateKey = ":".concat(topologyId); + var topologyName = $.url("?name"); + var tableStateKey = ":".concat(topologyName); var window = $.url("?window"); var sys = $.cookies.get("sys") || "false"; - var url = "/api/v1/topology/"+topologyId+"?sys="+sys; + var url = "/api/v1/topology/"+topologyName+"?sys="+sys; if(window) url += "&window="+window; $.extend( $.fn.dataTable.defaults, { stateSave: true, @@ -290,7 +290,7 @@

Topology resources

toggleChangeLogLevel = function (data) { renderLogLevelForm (template, data); } - searchForm.append(Mustache.render($(template).filter("#search-form-template").html(),{id: topologyId})); + searchForm.append(Mustache.render($(template).filter("#search-form-template").html(),{id: response["encodedId"]})); topologySummary.append(Mustache.render($(template).filter("#topology-summary-template").html(),response)); topologyResources.append(Mustache.render($(template).filter("#topology-resources-template").html(),response)); var displayResource = response["schedulerDisplayResource"];