remove "cancel" feature flag

remove "cancel" feature flag

--- src-cljs/frontend/components/pages/workflow.cljs
+++ src-cljs/frontend/components/pages/workflow.cljs
@@ -174,8 +174,7 @@
                    :status-class/running (icon/status-running)
                    :status-class/waiting (icon/status-queued))]
                 [:.status-string (string/replace (name status) #"-" " ")]]]
-              (cond (and (feature/enabled? :cancel-below-status)
-                         (cancelable-status? status))
+              (cond (cancelable-status? status)
                     [:div.cancel-button {:on-click #(transact-run-cancel this id vcs-type org-name project-name)}
                      (icon/status-canceled)
                      [:span "cancel"]]


removed code related to an ab test for convincing a user to pay us during their free trial

--- src-cljs/frontend/components/project/common.cljs
+++ src-cljs/frontend/components/project/common.cljs
@@ -66,7 +66,6 @@
                 [:a {:href plan-path} "Add a plan"]
                 " to keep running builds."))]))

-;; TODO: figure out where this is being tracked in mixpanel and launch one of these.
 (defn freemium-trial-html [plan project project-name days org-name plan-path]
   (html
     [:div.alert {:class "alert-success"}
@@ -74,16 +73,6 @@
                              org-name (plan-model/usable-containers plan) (pluralize days "day"))
              [:a.pay-now-plain-text {:href plan-path} "Please enter your payment information"]
              " before the trial expires to continue using these containers."
-             )]))
-
-(defn freemium-trial-html-b [plan project project-name days org-name plan-path]
-  (html
-    [:div.alert {:class "alert-success"}
-       (list (gstring/format "This project is covered by %s's trial of %s containers which expires in %s. "
-                             org-name (plan-model/usable-containers plan) (pluralize days "day"))
-             "Please enter your payment information before the trial expires to continue using these containers.    "
-             [:a.pay-now-button {:href plan-path}
-              [:button "Pay Now"]]
              )]))

 (defn trial-notice [data owner]


Add more tests for new type specs.

Add more tests for new type specs.

--- test/bytebuf/core_tests.clj
+++ test/bytebuf/core_tests.clj
@@ -140,6 +140,24 @@
       (let [[readed data] (buf/read* buffer spec)]
         (is (= readed 5))
         (is (= data ["12345"])))))
+
+  (testing "read/write float and double"
+    (let [spec (buf/spec (buf/float) (buf/double))
+          buffer (buf/allocate (buf/size spec))
+          data [(float 1.2) (double 3.55)]]
+      (buf/write! buffer data spec)
+      (let [[readed data'] (buf/read* buffer spec)]
+        (is (= readed (buf/size spec)))
+        (is (= data data')))))
+
+  (testing "read/write boolean and byte"
+    (let [spec (buf/spec (buf/bool) (buf/byte))
+          buffer (buf/allocate (buf/size spec))
+          data [true (byte 22)]]
+      (buf/write! buffer data spec)
+      (let [[readed data'] (buf/read* buffer spec)]
+        (is (= readed (buf/size spec)))
+        (is (= data data')))))
   )

 (deftest spec-data-with-dynamic-types


use namespace alias in tests

use namespace alias in tests

--- test/calfpath/core_test.clj
+++ test/calfpath/core_test.clj
@@ -1,29 +1,29 @@
 (ns calfpath.core-test
   (:require [clojure.test :refer :all]
-            [calfpath.core :refer :all]))
+            [calfpath.core :as c]))

 (deftest test-->uri
   (testing "No clause"
     (let [request {:uri "/user/1234/profile/compact/"}]
       (is (= 400
-            (:status (->uri request))))))
+            (:status (c/->uri request))))))
   (testing "One clause (no match)"
     (let [request {:uri "/hello/1234/"}]
       (is (= 400
-            (:status (->uri request
+            (:status (c/->uri request
                        "/user/:id/profile/:type/" [id type] (do {:status 200
                                                                  :body (format "ID: %s, Type: %s" id type)})))))))
   (testing "One clause (with match)"
     (let [request {:uri "/user/1234/profile/compact/"}]
       (is (= "ID: 1234, Type: compact"
-            (:body (->uri request
+            (:body (c/->uri request
                      "/user/:id/profile/:type/" [id type] {:status 200
                                                            :body (format "ID: %s, Type: %s" id type)}))))))
   (testing "Two clauses (no match)"
     (let [request {:uri "/hello/1234/"}]
       (is (= 400
-            (:status (->uri request
+            (:status (c/->uri request
                        "/user/:id/profile/:type/" [id type] {:status 200
                                                              :body (format "ID: %s, Type: %s" id type)}
                        "/user/:id/permissions/"   [id]      {:status 200
@@ -31,7 +31,7 @@
   (testing "Two clauses (no match, custom default)"
     (let [request {:uri "/hello/1234/"}]
       (is (= 404
-            (:status (->uri request
+            (:status (c/->uri request
                        "/user/:id/profile/:type/" [id type] {:status 200
                                                              :body (format "ID: %s, Type: %s" id type)}
                        "/user/:id/permissions/"   [id]      {:status 200
@@ -41,7 +41,7 @@
   (testing "Two clause (with match)"
     (let [request {:uri "/user/1234/permissions/"}]
       (is (= "ID: 1234"
-            (:body (->uri request
+            (:body (c/->uri request
                      "/user/:id/profile/:type/" [id type] {:status 200
                                                            :body (format "ID: %s, Type: %s" id type)}
                      "/user/:id/permissions/"   [id]      {:status 200
@@ -52,23 +52,23 @@
   (testing "No clause"
     (let [request {:request-method :get}]
       (is (= 405
-            (:status (->method request))))))
+            (:status (c/->method request))))))
   (testing "One clause (no match)"
     (let [request {:request-method :get}]
       (is (= 405
-            (:status (->method request
+            (:status (c/->method request
                        :put {:status 200
                              :body   "Updated"}))))))
   (testing "One clause (with match)"
     (let [request {:request-method :get}]
       (is (= 200
-            (:status (->method request
+            (:status (c/->method request
                        :get {:status 200
                              :body   "Data"}))))))
   (testing "Two clauses (no match)"
     (let [request {:request-method :delete}]
       (is (= 405
-            (:status (->method request
+            (:status (c/->method request
                        :get {:status 200
                              :body   "Data"}
                        :put {:status 200
@@ -76,7 +76,7 @@
   (testing "Two clauses (no match, custom default)"
     (let [request {:request-method :delete}]
       (is (= 404
-            (:status (->method request
+            (:status (c/->method request
                        :get {:status 200
                              :body   "Data"}
                        :put {:status 200
@@ -86,7 +86,7 @@
   (testing "Two clauses (with match)"
     (let [request {:request-method :put}]
       (is (= "Updated"
-            (:body (->method request
+            (:body (c/->method request
                      :get {:status 200
                            :body   "Data"}
                      :put {:status 200
@@ -105,59 +105,59 @@
         not-found {:status 404
                    :body   "Not found"}]
     (testing "->get"
-      (is (= 405 (:status (->get request-put ok))))
-      (is (= 404 (:status (->get request-put ok not-found))))
-      (is (= 200 (:status (->get request-get ok))))
-      (is (= 200 (:status (->get request-get ok not-found)))))
+      (is (= 405 (:status (c/->get request-put ok))))
+      (is (= 404 (:status (c/->get request-put ok not-found))))
+      (is (= 200 (:status (c/->get request-get ok))))
+      (is (= 200 (:status (c/->get request-get ok not-found)))))
     (testing "->head"
-      (is (= 405 (:status (->head request-put ok))))
-      (is (= 404 (:status (->head request-put ok not-found))))
-      (is (= 200 (:status (->head request-head ok))))
-      (is (= 200 (:status (->head request-head ok not-found)))))
+      (is (= 405 (:status (c/->head request-put ok))))
+      (is (= 404 (:status (c/->head request-put ok not-found))))
+      (is (= 200 (:status (c/->head request-head ok))))
+      (is (= 200 (:status (c/->head request-head ok not-found)))))
     (testing "->options"
-      (is (= 405 (:status (->options request-put ok))))
-      (is (= 404 (:status (->options request-put ok not-found))))
-      (is (= 200 (:status (->options request-options ok))))
-      (is (= 200 (:status (->options request-options ok not-found)))))
+      (is (= 405 (:status (c/->options request-put ok))))
+      (is (= 404 (:status (c/->options request-put ok not-found))))
+      (is (= 200 (:status (c/->options request-options ok))))
+      (is (= 200 (:status (c/->options request-options ok not-found)))))
     (testing "->put"
-      (is (= 405 (:status (->put request-get ok))))
-      (is (= 404 (:status (->put request-get ok not-found))))
-      (is (= 200 (:status (->put request-put ok))))
-      (is (= 200 (:status (->put request-put ok not-found)))))
+      (is (= 405 (:status (c/->put request-get ok))))
+      (is (= 404 (:status (c/->put request-get ok not-found))))
+      (is (= 200 (:status (c/->put request-put ok))))
+      (is (= 200 (:status (c/->put request-put ok not-found)))))
     (testing "->post"
-      (is (= 405 (:status (->post request-put ok))))
-      (is (= 404 (:status (->post request-put ok not-found))))
-      (is (= 200 (:status (->post request-post ok))))
-      (is (= 200 (:status (->post request-post ok not-found)))))
+      (is (= 405 (:status (c/->post request-put ok))))
+      (is (= 404 (:status (c/->post request-put ok not-found))))
+      (is (= 200 (:status (c/->post request-post ok))))
+      (is (= 200 (:status (c/->post request-post ok not-found)))))
     (testing "->delete"
-      (is (= 405 (:status (->delete request-put ok))))
-      (is (= 404 (:status (->delete request-put ok not-found))))
-      (is (= 200 (:status (->delete request-delete ok))))
-      (is (= 200 (:status (->delete request-delete ok not-found)))))))
+      (is (= 405 (:status (c/->delete request-put ok))))
+      (is (= 404 (:status (c/->delete request-put ok not-found))))
+      (is (= 200 (:status (c/->delete request-delete ok))))
+      (is (= 200 (:status (c/->delete request-delete ok not-found)))))))

 (defn composite
   [request]
-  (->uri request
-    "/user/:id/profile/:type/" [id type] (->method request
+  (c/->uri request
+    "/user/:id/profile/:type/" [id type] (c/->method request
                                            :get {:status 200
                                                  :body (format "Compact profile for ID: %s, Type: %s" id type)}
                                            :put {:status 200
                                                  :body (format "Updated ID: %s, Type: %s" id type)})
-    "/user/:id/permissions/"   [id]      (->post request {:status 201
+    "/user/:id/permissions/"   [id]      (c/->post request {:status 201
                                                           :body "Created new permission"})))

 (def composite-fn
-  (make-uri-handler
+  (c/make-uri-handler
     "/user/:id/profile/:type/" (fn [request {:keys [id type]}]
-                                 (->method request
+                                 (c/->method request
                                    :get {:status 200
                                          :body (format "Compact profile for ID: %s, Type: %s" id type)}
                                    :put {:status 200
                                          :body (format "Updated ID: %s, Type: %s" id type)}))
     "/user/:id/permissions/"   (fn [request {:keys [id]}]
-                                 (->post request {:status 201
+                                 (c/->post request {:status 201
                                                   :body "Created new permission"}))
     (fn [_] {:status 400
              :headers {"Content-Type" "text/plain"}


Add a test that runs the Aeron driver

Add a test that runs the Aeron driver

--- test/desdemona/cli_test.clj
+++ test/desdemona/cli_test.clj
@@ -51,4 +51,8 @@
     (let [[result stdout] (with-fake-launcher-side-effects
                             (aeron/-main "--xyzzy"))]
       (is (= result [::exited 1]))
-      (is (= stdout (s/join \newline (concat error-lines usage-lines)))))))
+      (is (= stdout (s/join \newline (concat error-lines usage-lines))))))
+  (testing "regular run"
+    (let [[result stdout] (with-fake-launcher-side-effects (aeron/-main))]
+      (is (= result ::blocked-forever))
+      (is (= stdout "Launched the Media Driver. Blocking forever...\n")))))


Hm; I was really expecting this to work.

--- test/desdemona/cli_test.clj
+++ test/desdemona/cli_test.clj
@@ -5,7 +5,8 @@
    [desdemona.launcher.utils :as utils]
    [clojure.test :refer [deftest testing is]]
    [clojure.string :as s]
-   [clojure.core.async :as a])
+   [clojure.core.async :as a]
+   [taoensso.timbre :refer [spy info]])
   (:import
    [java.io StringWriter]))

@@ -119,5 +120,34 @@

 (deftest peers-main-tests
   (testing "first argument must be an integer"
-    (is (thrown-with-msg? NumberFormatException #"BOGUS"
-         (peers/-main "BOGUS")))))
+    (is (thrown-with-msg?
+         NumberFormatException #"BOGUS"
+         (peers/-main "BOGUS"))))
+  (testing "happy case"
+    (let [group (gensym)
+          n-peers 6
+          peers (for [_ (range n-peers)] (gensym))
+          events (atom [])
+          redef-pairs (for [sym ['onyx.api/start-peer-group
+                                 'onyx.api/start-env
+                                 'onyx.api/start-peers
+                                 'onyx.api/shutdown-peer
+                                 'onyx.api/shutdown-peers
+                                 'onyx.api/shutdown-peer-group
+                                 'clojure.core/shutdown-agents]]
+                        [(spy (resolve sym))
+                         (fn [& args]
+                           (let [event (into [sym] args)]
+                             (swap! events conj event)))])
+          redefs (spy (into {} redef-pairs))]
+      (with-redefs-fn redefs
+        (fn []
+          (info "BEFORE" @events)
+          (let [[result stdout] (with-fake-launcher-side-effects
+                                  (peers/-main (str n-peers)))]
+            (info "AFTER" @events)
+            (is (= result ::blocked-forever))
+            (is (= stdout (s/join \newline
+                                  ["Connecting to Zookeeper:  zk:2181"
+                                   "Started peers. Blocking forever."
+                                   ""])))))))))


correct namespace in template

correct namespace in template

--- src/leiningen/new/chestnut/src/cljs/chestnut/core_rum.cljs
+++ src/leiningen/new/chestnut/src/cljs/chestnut/core_rum.cljs
@@ -1,4 +1,4 @@
-(ns asdf.core
+(ns {{project-ns}}.core
   (:require [rum.core :as rum]))

 (enable-console-print!)


Add verification of collection links in JSON response to collection creation REST API tests.

--- test/fcms/integration/rest_api/collection/collection_create.clj
+++ test/fcms/integration/rest_api/collection/collection_create.clj
@@ -2,6 +2,7 @@
   (:require [midje.sweet :refer :all]
             [fcms.lib.resources :refer :all]
             [fcms.resources.collection :refer :all]
+            [fcms.lib.body :refer (verify-collection-links)]
             [fcms.lib.rest-api-mock :refer :all]
             [fcms.resources.common :as common]
             [fcms.resources.collection :as collection]))
@@ -59,7 +60,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c
@@ -74,7 +76,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => (str "/" generated-slug)
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links generated-slug (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection "this-is-also-a-slug") => (contains {
         :slug generated-slug
@@ -89,7 +92,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c
@@ -103,7 +107,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c-1"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links "c-1" (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection "c-1") => (contains {
         :slug "c-1"
@@ -118,7 +123,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/another-c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links "another-c" (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection "another-c") => (contains {
         :slug "another-c"
@@ -133,7 +139,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c
@@ -147,7 +154,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c
@@ -161,7 +169,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c
@@ -175,7 +184,8 @@
         (:status response) => 201
         (response-mime-type response) => (mime-type :collection)
         (response-location response) => "/c"
-        (json? response) => true)
+        (json? response) => true
+        (verify-collection-links c (:links (body-from-response response))))
       ;; Get the created collection and make sure it's right
       (collection/get-collection c) => (contains {
         :slug c


(maint) Disable EndpointIdentification

(maint) Disable EndpointIdentification

Previously, Jetty disabled Endpoint Identification by default as it is a best
practice for most webservers who often cannot identify clients
connecting to it. However, in 9.4.15 Jetty changed this default to
"HTTPS", which is the best practice for _client_ SslContexts. This
caused serious breakages throughout the Jetty ecosystem and since 9.4.16
Jetty introduced static inner classes of SslContextFactory, named Server
and Client, to create the correct contexts for each type of consumer.

Unfortunately, because we subclass SslContextFactory with our own
InternalSslContextFactory that overrides CRL handling, using these static
inner class factories is problematic. Consequently, this patch takes the
approach of simply setting the Endpoint Identification Algorithm to null
as was previously the default (and necessary in most server
environments).

This will cause a warning of overriding a deprecated method during
compilation in newer Java versions and our approach to handling CRLs
will need to be reworked should we use this codebase as a basis for a
trapperkeeper-webserver-jetty10 project.

For more info see linked issues to the implementing PR here:
https://github.com/eclipse/jetty.project/pull/3480/files#diff-58640db0f8f2cd84b7e653d1c1540913

--- src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
+++ src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
@@ -197,6 +197,7 @@
                   (.setKeyStore (:keystore keystore-config))
                   (.setKeyStorePassword (:key-password keystore-config))
                   (.setTrustStore (:truststore keystore-config))
+                  (.setEndpointIdentificationAlgorithm nil)
                   ;; Need to clear out the default cipher suite exclude list so
                   ;; that Jetty doesn't potentially remove one or more ciphers
                   ;; that we want to be included.


CMR-1303: Commenting out the test until the issue is resolved.

--- metadata-db-app/test/cmr/metadata_db/test/data/oracle/concepts.clj
+++ metadata-db-app/test/cmr/metadata_db/test/data/oracle/concepts.clj
@@ -45,8 +45,8 @@
                  (= :a 5))
            (c/find-params->sql-clause {:a 5 :b "bravo"})))))

-
-(deftest db-result->concept-map-test
+;; This test is commented out until CMR-1303 is resolved
+#_(deftest db-result->concept-map-test
   (let [db (->> (mdb-config/db-spec "metadata-db-test")
                 oracle/create-db
                 (#(lifecycle/start % nil)))]


CMR-2673: Fixing issues with the RefreshIndexNamesCacheJob

--- search-app/src/cmr/search/data/elastic_search_index.clj
+++ search-app/src/cmr/search/data/elastic_search_index.clj
@@ -44,13 +44,17 @@
                  :collections \"1_collections\"}}"
   :index-names)

+(def index-names-cache-key
+  "The key used for index names in the index cache."
+  :concept-indices)
+
 ;; A job for refreshing the index names cache.
 (defjob RefreshIndexNamesCacheJob
   [ctx system]
   (let [context {:system system}
         index-names (fetch-concept-type-index-names context)
         cache (cache/context->cache context index-cache-name)]
-    (cache/set-value cache index-cache-name index-names)))
+    (cache/set-value cache index-names-cache-key index-names)))

 (def refresh-index-names-cache-job
   {:job-type RefreshIndexNamesCacheJob
@@ -61,8 +65,9 @@
   "Fetch index names associated with concepts."
   [context]
   (cache/get-value (cache/context->cache context index-cache-name)
-                   :concept-indices
+                   index-names-cache-key
                    (partial fetch-concept-type-index-names context)))
+
 (defn- get-granule-index-names
   "Fetch index names associated with granules excluding rebalancing collections indexes"
   [context]


Fix broken test fixture

Fix broken test fixture

--- test/time_tracker/fixtures.clj
+++ test/time_tracker/fixtures.clj
@@ -4,11 +4,12 @@
             [time-tracker.db :as db]
             [time-tracker.web.service :refer [app]]
             [time-tracker.auth.core :as auth]
-            [time-tracker.auth.test-helpers :refer [fake-token->credentials]])
+            [time-tracker.auth.test-helpers :refer [fake-token->credentials]]
+            [time-tracker.core :as core])
   (:use org.httpkit.server))

 (defn init! [f]
-  (time-tracker.web.service/init!)
+  (core/init!)
   (f))

 (defn destroy-db []


Documentation of hellhound.kafka.producer has been improved

--- extra_components/kafka/src/clj/hellhound/kafka/producers.clj
+++ extra_components/kafka/src/clj/hellhound/kafka/producers.clj
@@ -1,4 +1,14 @@
 (ns hellhound.kafka.producers
+  "This namespace contains thin wrappers around the official
+  Kafka Producer API. Here is a very simple example:
+
+  ```clj
+  (def p (make-producer {\"bootstrap.servers\" \"localhost:9092\"}))
+  (send p \"sometopic\" \"something\")
+  (send p \"sometopic\" \"something else\")
+  (close p)
+  ```
+  For more information please consult the KafkaProducer javadocs."
   (:require
    [hellhound.kafka.core :as core])

@@ -15,6 +25,10 @@
 (def default-value-serializer (StringSerializer.))

 (defn ^KafkaProducer make-producer
+  "Create a `KafkaProducer` instance by the given `config` map and optional
+  `key-serializer` and `value-serializer` which are responsible for serializing
+  key and value of records. For more information on them please checkout the
+  javadocs for `org.apache.kafka.common.serialization` package."
   ([config]
    (make-producer config default-key-serializer default-value-serializer))

@@ -24,6 +38,9 @@
 ;

 (defn send
+  "Send the given `key` (optional) and `value` to the given `topic` using
+  the given `producer` and the optional `partition` and returns a java
+  future object."
   ([^Producer producer topic v]
    (let [record (ProducerRecord. topic v)]
      (.send producer record)))
@@ -41,11 +58,6 @@
      (.send producer record))))

 (defn close
+  "Close the given `producer` thread pool."
   [^Producer producer]
   (.close producer))
-
-(comment
-  (def p (make-producer {"bootstrap.servers" "localhost:9092"}))
-  (send p "something" "11111111")
-  (send p "something" "22222")
-  (close p))


edited animation.clj

edited animation.clj

--- src/maqueta/hello/animation.clj
+++ src/maqueta/hello/animation.clj
@@ -3,11 +3,9 @@

 (ns maqueta.hello.animation
   (:use (maqueta application assets))
-  (:import com.jme3.math.ColorRGBA
-           com.jme3.math.Vector3f
-           com.jme3.scene.Node
-           (com.jme3.animation AnimControl LoopMode)
-           com.jme3.light.DirectionalLight))
+  (:import com.jme3.light.DirectionalLight
+           (com.jme3.math ColorRGBA Vector3f)
+           (com.jme3.animation AnimControl LoopMode)))

 (def light (DirectionalLight.))

@@ -24,8 +22,6 @@
       (.setAnim "Walk" 0.5)
       (.setLoopMode LoopMode/Loop))))

-(def on-action {:key-space walk})
-
 (defn cycle-done
   [app control channel]
   (doto channel
@@ -33,22 +29,21 @@
     (.setLoopMode LoopMode/DontLoop)
     (.setSpeed 1)))

-(def on-anim-cycle-done {"Walk" cycle-done})
-
 (defn setup-fn
   [app]
   (let [root-node (.getRootNode app)
         viewport (.getViewPort app)]
     (.setBackgroundColor viewport ColorRGBA/LightGray)
     (.setDirection light (.normalizeLocal (Vector3f. -0.1 -1 -1)))
-    (.addLight root-node light)
     (.setLocalScale player (Vector3f. 0.5 0.5 0.5))
     (.addListener control app)
-    (.setAnim channel "stand")))
+    (.setAnim channel "stand")
+    (doto root-node
+      (.attachChild player)
+      (.addLight light))))

 (defn -main
   [& args]
-  (.start (make-app :root-node player
-                    :setup-fn setup-fn
-                    :on-anim-cycle-done on-anim-cycle-done
-                    :on-action on-action)))
+  (.start (make-app :setup-fn setup-fn
+                    :on-action {:key-space walk}
+                    :on-anim-cycle-done {"Walk" cycle-done})))


changes to accomadate the new github data fetch fn

--- src/cljs/dashboard_clj/widgets/github_repo_stats.cljs
+++ src/cljs/dashboard_clj/widgets/github_repo_stats.cljs
@@ -8,19 +8,20 @@
   [:div {:class "github-repo-stats"}
    [:img {:class "github-logo" :src "/images/github_mark.png"}]
    [:h2 {:class "title" } (:repo-name w)]
-   [:h4 {:class "total-commits"} (str "commits: "(reduce + (map #(second %) (get-in @data [:data :commit-data]))))]
+   [:h4 {:class "total-commits"} (str "commits: "(reduce + (map #(second %) (get-in @data [:data :weekly-commit-breakdown]))))]
    [:table {:class "contributors"}
+    [:tbody
     [:tr
      [:th "contributors"]]
      (doall (for [contributor (get-in @data [:data :contributors])]
               [:tr {:key contributor}
-               [:th (str contributor)]]))]
+               [:th (str contributor)]]))]]
    [:div {:class "commit-chart" :style { :width "95%" :height "40%"}}
     [charts/line-chart {:chart-options
                         {:title {:text text}
-                         :xAxis {:categories (mapv first (get-in @data [:data :commit-data]))}
+                         :xAxis {:categories (mapv first (get-in @data [:data :weekly-commit-breakdown]))}
                          :series [{:name "commits"
-                                   :data (mapv second (get-in @data [:data :commit-data]))}]}}]]])
+                                   :data (mapv second (get-in @data [:data :weekly-commit-breakdown]))}]}}]]])


CMR-3780: Refactored enable/disable of tag / tag association writes

--- search-app/src/cmr/search/api/tags_api.clj
+++ search-app/src/cmr/search/api/tags_api.clj
@@ -46,14 +46,11 @@
   "Processes a create tag request."
   [context headers body]
   (verify-tag-modification-permission context :create)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (let [result (tagging-service/create-tag context body)
-           status-code (if (= 1 (:revision-id result)) 201 200)]
-       (tag-api-response status-code result)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (let [result (tagging-service/create-tag context body)
+        status-code (if (= 1 (:revision-id result)) 201 200)]
+    (tag-api-response status-code result)))

 (defn get-tag
   "Retrieves the tag with the given tag-key."
@@ -64,65 +61,48 @@
   "Processes a request to update a tag."
   [context headers body tag-key]
   (verify-tag-modification-permission context :update)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (tag-api-response (tagging-service/update-tag context tag-key body)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (tag-api-response (tagging-service/update-tag context tag-key body)))

 (defn delete-tag
   "Deletes the tag with the given tag-key."
   [context tag-key]
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (verify-tag-modification-permission context :delete)
-     (tag-api-response (tagging-service/delete-tag context tag-key)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (verify-tag-modification-permission context :delete)
+  (tag-api-response (tagging-service/delete-tag context tag-key)))

 (defn associate-tag-to-collections
   "Associate the tag to a list of collections."
   [context headers body tag-key]
   (verify-tag-modification-permission context :update)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (tag-api-response (tagging-service/associate-tag-to-collections context tag-key body)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (tag-api-response (tagging-service/associate-tag-to-collections context tag-key body)))

 (defn disassociate-tag-to-collections
   "Disassociate the tag to a list of collections."
   [context headers body tag-key]
   (verify-tag-modification-permission context :update)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (tag-api-response (tagging-service/disassociate-tag-to-collections context tag-key body)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (tag-api-response (tagging-service/disassociate-tag-to-collections context tag-key body)))

 (defn associate-tag-by-query
   "Processes a request to associate a tag."
   [context headers body tag-key]
   (verify-tag-modification-permission context :update)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (tag-api-response (tagging-service/associate-tag-by-query context tag-key body)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (tag-api-response (tagging-service/associate-tag-by-query context tag-key body)))
+
 (defn disassociate-tag-by-query
   "Processes a request to disassociate a tag."
   [context headers body tag-key]
   (verify-tag-modification-permission context :update)
-  (if (common-enabled/app-write-enabled? context)
-   (do
-     (validate-tag-content-type headers)
-     (tag-api-response (tagging-service/disassociate-tag-by-query context tag-key body)))
-   (errors/throw-service-error :service-unavailable
-                               (common-enabled/service-write-disabled-message "search"))))
+  (common-enabled/validate-write-enabled context "search")
+  (validate-tag-content-type headers)
+  (tag-api-response (tagging-service/disassociate-tag-by-query context tag-key body)))

 (defn search-for-tags
   [context params]


[frontend]: Disable import-export test because of bug in recent Firefox

--- frontend/test/warehouse/selenium/test.clj
+++ frontend/test/warehouse/selenium/test.clj
@@ -55,7 +55,9 @@
         (.executePhantomJS driver script (make-array Object 0)))
       (send-keys "//input[@type='file']" path))))

-(deftest import-export []
+;; todo: uncomment when firefox 56 is released
+;; https://github.com/mozilla/geckodriver/issues/858
+#_(deftest import-export []
   ; reset env
   (to base-url)
   (execute-script "localStorage.clear();")


Added code to read PlanePlotter daily report log databases.

The daily report logs have names like "pp_report2015031500.sqb".

--- src/com/lemondronor/orbital_detector/planeplotter.clj
+++ src/com/lemondronor/orbital_detector/planeplotter.clj
@@ -4,6 +4,7 @@
             [clj-time.format :as timefmt]
             [clojure.data.csv :as csv]
             [clojure.java.io :as io]
+            [clojure.java.jdbc :as jdbc]
             [clojure.string :as string])
   (:import (java.util.zip GZIPInputStream)))

@@ -44,3 +45,31 @@
        log-reader
        csv/read-csv
        (map parse-log-csv)))
+
+
+(defn parse-report-flightid [flightid]
+  (string/split flightid #";"))
+
+
+(defn report-db-spec [path]
+  {:classname "org.sqlite.JDBC"
+   :subprotocol "sqlite"
+   :subname path})
+
+
+(defn parse-report-db-record [r]
+  (let [[icao callsign registration] (parse-report-flightid (:flightid r))]
+    (assoc
+     r
+     :icao icao
+     :callsign callsign
+     :registration registration
+     :firsttime (timecoerce/to-local-date-time (* 1000 (long (:firsttime r))))
+     :lasttime (timecoerce/to-local-date-time (* 1000 (long (:lasttime r)))))))
+
+
+(defn reports [path]
+  (map parse-report-db-record
+       (jdbc/query
+        (report-db-spec path)
+        "SELECT * from PPreport;")))


Update galleon.clj

Update galleon.clj

--- src/galleon.clj
+++ src/galleon.clj
@@ -10,7 +10,6 @@
             [gangway.enqueue :as gw-enqueue])
   (:import (java.io File)))

-(def default-config-path "/etc/galleon.edn")
 (def system nil)

 (defn file-exists? [path]


* samples/repl/src/repl/test.cljs: fix comment in sample repl test.cljs

--- samples/repl/src/repl/test.cljs
+++ samples/repl/src/repl/test.cljs
@@ -30,7 +30,8 @@
       (def env (browser/repl-env))
       (repl/repl env))

-  ;; Open the file samples/repl/index.html
+  ;; Open http://localhost:9000/ in a browser. When this page is loaded
+  ;; it will connect to the REPL.

   ;; Evaluate some basic forms
   (+ 1 1)


deps testing

deps testing

--- test/overtone/deps_test.clj
+++ test/overtone/deps_test.clj
@@ -17,9 +17,9 @@
     (satisfy-deps :bar)
     (Thread/sleep 100)
     (satisfy-deps :baz)
-    (Thread/sleep 200)
+    (Thread/sleep 100)
     (on-deps #{:foo :baz}
             #(swap! log conj :e))
-    (Thread/sleep 300)
+    (Thread/sleep 100)
     (is (= [:a :b :c :d :e] @log))))


update error-handler test case for run-pipeline

--- test/papaline/core_test.clj
+++ test/papaline/core_test.clj
@@ -85,9 +85,18 @@
         ff2 (fn [a] (inc a))]
     (is (= 2 (run-pipeline-wait (pipeline [fff ff2]))))))

-(deftest test-error-handler
-  (let [e (atom false)
+(deftest test-error-handler-sync
+  (let [e (atom 0)
         f (fn [] (throw (ex-info "expected error.")))
-        p (pipeline [f] :error-handler (fn [_ _] (swap! e (constantly true))))]
+        p (pipeline [f] :error-handler (fn [_ _] (swap! e inc)))]
     (try (run-pipeline-wait p) (catch Exception e))
-    (is @e)))
+    (is (= 1 @e))))
+
+(deftest test-error-handler-async
+  (let [e (atom 0)
+        sync (chan)
+        f (fn [] (throw (ex-info "expected error")))
+        p (pipeline [f] :error-handler (fn [_ _] (swap! e inc) (>!! sync 1)))]
+    (run-pipeline p)
+    (<!! sync)
+    (is (= 1 @e))))


Better document onyx/type.

Better document onyx/type.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -169,7 +169,7 @@
                    :added "0.8.0"}

                   :onyx/type
-                  {:doc "The role that this task performs. `:input` reads from a data source. `:function` applies a transformation. `:reduce` is a windowed task that reduces data, optionally triggers downstream via `:trigger/emit`, and doesn't pass transformed segments downstream. `:output` writes data as the terminal node in a workflow.."
+                  {:doc "The role that this task performs. `:input` reads from a data source, and must be a source node. `:function` applies a transformation and must be an intermediate or terminal node. `:reduce` is a task that must contain windows, may be either a terminal or intermediate node, and does not pass transformed segments downstream. When `:reduce` task is an intermediate node, a trigger with `:trigger/emit` must be set on the task. `:output` writes data as the terminal node in a workflow."
                    :type :keyword
                    :tags [:task]
                    :choices [:input :function :output :reduce]


Provide task states order.

Provide task states order.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -2030,6 +2030,7 @@
    :state-refinement [:refinement/create-state-update :refinement/apply-state-update]
    :state-event [:event-type :task-event :segment :grouped?  :group-key :lower-bound
                  :upper-bound :log-type :trigger-update :aggregation-update :window :next-state]
+   :task-states [:recover :processing :start-iteration :barriers :process-batch :heartbeat]
    :event-map [:onyx.core/task-map
                :onyx.core/catalog
                :onyx.core/workflow


Cosmetic.

Cosmetic.

--- src/onyx/peer/task_pipeline.clj
+++ src/onyx/peer/task_pipeline.clj
@@ -182,7 +182,7 @@
   component/Lifecycle

   (start [component]
-    (taoensso.timbre/info "Starting Task Pipeline for " (:task/name (:task payload)))
+    (taoensso.timbre/info "Starting Task Pipeline for" (:task/name (:task payload)))

     (let [open-session-kill-ch (chan 0)
           read-batch-ch (chan 0)


cleanup of test code

cleanup of test code

--- test/sparkling/api_test.clj
+++ test/sparkling/api_test.clj
@@ -135,7 +135,7 @@
                     (testing
                       "filter returns an RDD formed by selecting those elements of the source on which func returns true"
                       (is (equals-ignore-order? (-> (s/parallelize c [1 2 3 4 5 6])
-                                                    (s/filter (fn [x] (even? x)))
+                                                    (s/filter even?)
                                                     s/collect
                                                     vec)
                                                 [2 4 6])))


Fix support for nested subgroups.

Fix support for nested subgroups.

Still don't like having to separate examples
from subgroups by examining literal forms.

Maybe I should put back an "it" macro for
each example.

--- src/main/clojure/com/stuartsierra/lazytest/groups.clj
+++ src/main/clojure/com/stuartsierra/lazytest/groups.clj
@@ -5,7 +5,7 @@
         [com.stuartsierra.lazytest.contexts
          :only (context context? with-context find-locals)]))

-(defrecord Group [contexts examples])
+(defrecord Group [contexts examples subgroups])

 (defn group?
   "True if x is an example group."
@@ -23,7 +23,7 @@
             (every? group? subgroups)
             (or-nil map? metadata)]
       :post [(group? %)]}
-     (Group. contexts examples nil metadata)))
+     (Group. contexts examples subgroups nil metadata)))

 (defmacro example
   "Creates an example function, using current context locals for
@@ -98,8 +98,8 @@
   Option :given is followed by a vector of symbol-expression pairs.
   All examples in the group will run with the symbol bound to the
   state returned by that expression."
+  {::subgroup true}
   [& body]
-  {::subgroup true}
   (let [[docstring body] (get-arg string? body)
         [opts body] (get-options body)
         givens (interleave (firsts (:given opts))
@@ -109,7 +109,6 @@
         [examples subgroups] (split-examples-and-subgroups body)]
     `(with-meta (group ~bindings (group-examples ~@examples) ~subgroups)
        ~(standard-metadata &form docstring))))
-

 ;;; Assertions

@@ -253,3 +252,37 @@
         (assert (integer? (:line m)))
         (assert (nil? (:name m)))
         (assert (= '[x y] (:locals m)))))))
+
+(let [g (description :given [x 1 y 2]
+                     (= 1 x)
+                     "foo" (= y 2)
+                     (description (= y 2)))]
+  (assert (group? g))
+  (assert (= 2 (count (:contexts g))))
+  (let [exs (:examples g)]
+    (assert (vector? exs))
+    (assert (= 2 (count exs)))
+    (assert (every? fn? exs))
+    (let [[ex1 ex2] exs]
+      (assert (true? (ex1 1 2)))
+      (assert (true? (ex2 1 2)))
+      (let [m (meta ex1)]
+        (assert (nil? (:doc m)))
+        (assert (= *ns* (:ns m)))
+        (assert (string? (:file m)))
+        (assert (integer? (:line m)))
+        (assert (nil? (:name m)))
+        (assert (= '[x y] (:locals m))))
+      (let [m (meta ex2)]
+        (assert (= "foo" (:doc m)))
+        (assert (= *ns* (:ns m)))
+        (assert (string? (:file m)))
+        (assert (integer? (:line m)))
+        (assert (nil? (:name m)))
+        (assert (= '[x y] (:locals m))))))
+  (let [sgs (:subgroups g)]
+    (assert (= 1 (count sgs)))
+    (let [sg (first sgs)]
+      (assert (group? sg))
+      (assert (= 1 (count (:examples sg))))
+      (assert (= 2 (count (:contexts sg)))))))


cleaned up app state section a bit more

cleaned up app state section a bit more

--- src/tutorial/untangled_tutorial/F_Untangled_Initial_App_State.cljs
+++ src/tutorial/untangled_tutorial/F_Untangled_Initial_App_State.cljs
@@ -9,9 +9,6 @@
             [cljs.reader :as r]
             [untangled.client.mutations :as m]))

-(defmethod m/mutate 'doit [{:keys [state]} k p]
-  {:action (fn [] (swap! state update-in [:child/by-id 1 :x] inc))})
-
 (defui Child
   static uc/InitialAppState
   (initial-state [this params] {:id 1 :x 1})
@@ -22,21 +19,20 @@
   Object
   (render [this]
     (let [{:keys [x]} (om/props this)]
-      (dom/p nil (str "Child: " x)
-             (dom/button #js {:onClick #(om/transact! this '[(doit)])} "!!!")))))
+      (dom/p nil (str "Child x: " x)))))

 (def ui-child (om/factory Child))

 (defui Root
   static uc/InitialAppState
-  (initial-state [this params] {:r 0 :child (uc/initial-state Child {})})
+  (initial-state [this params] {:root-prop 42 :child (uc/initial-state Child {})})
   static om/IQuery
-  (query [this] [:r {:child (om/get-query Child)}])
+  (query [this] [:ui/react-key :root-prop {:child (om/get-query Child)}])
   Object
   (render [this]
-    (let [{:keys [r child]} (om/props this)]
-      (dom/div nil
-        (str "Root: " r)
+    (let [{:keys [ui/react-key root-prop child]} (om/props this)]
+      (dom/div #js {:style #js {:border "1px solid black"} :key react-key}
+        (str "Root prop: " root-prop)
         (ui-child child)))))

 (defcard-doc
@@ -87,7 +83,15 @@
   1. Pull the initial state and use that as base app state
   2. Ensure that it is normalized by Om
   3. Will do a post-initialization step to ensure alternate branches of to-one unions are initialized.
+  ")

+(defcard sample-app
+  "This card shows the app from above, actively rendered. The resulting normalized app database is shown below the UI."
+  (untangled-app Root)
+  {}
+  {:inspect-data true})
+
+(defcard-doc "
   ## Union Initialization

   The last step mentioned in the prior section is particularly handy. In stock Om you to need to do some special backflips in order
@@ -178,3 +182,4 @@
   At some point you'll also be interested in setting up [a development environment](#!/untangled_tutorial.F_Untangled_DevEnv)
   for your own project.
   ")
+


CMR-3613: Really addressed review comments.

--- access-control-app/src/cmr/access_control/data/group_fetcher.clj
+++ access-control-app/src/cmr/access_control/data/group_fetcher.clj
@@ -2,9 +2,8 @@
   "Stores the group id to group legacy guid mapping in a consistent cache."
   (:require
    [cmr.access-control.services.group-service :as group-service]
-   [cmr.common-app.services.search.parameter-validation :as parameter-validation]
    [cmr.common.cache :as c]
-   [cmr.common.cache.single-thread-lookup-cache :as stl-cache]))
+   [cmr.common.cache.in-memory-cache :as mem-cache]))

 (def group-cache-key
   "The cache key to use when storing with caches in the system."
@@ -13,54 +12,15 @@
 (defn create-cache
   "Creates an instance of the cache."
   []
-  (stl-cache/create-single-thread-lookup-cache))
+  (mem-cache/create-in-memory-cache))

-(defn- legacy-guid->cache-value
-  "Returns the value that is stored in cache for the given legacy guid.
-   If legacy guid is nil, we store an empty string as the value for legacy guid.
-   This way, we can distinguish the case when a group id does not have a legacy guid
-   from a group id is not in the cache in one map lookup."
-  [legacy-guid]
-  (if (nil? legacy-guid) "" legacy-guid))
-
-(defn- cache-value->legacy-guid
-  "Returns the legacy guid from the stored cache value."
-  [cache-value]
-  ;; retuns nil if cached value is an empty string
-  (when (seq cache-value) cache-value))
-
-(defn- retrieve-group-id-to-legacy-guid-map
-  [context]
-  (let [groups (group-service/search-for-groups
-                context {"page-size" parameter-validation/max-page-size})]
-    (into {} (for [group (get-in groups [:results :items])
-                   :let [legacy-guid (:legacy_guid group)]]
-               [(:concept_id group) (legacy-guid->cache-value legacy-guid)]))))
-
-(defn refresh-cache
-  "Refreshes the group id to group legacy guid map in the cache."
-  [context]
-  (let [cache (c/context->cache context group-cache-key)]
-    (c/set-value cache group-cache-key
-                 (retrieve-group-id-to-legacy-guid-map context))))
+(defn- get-group-legacy-guid
+  "Returns the group legacy guid for the given group concept id by executing a search."
+  [context group-id]
+  (:legacy-guid (group-service/get-group-by-concept-id context group-id)))

 (defn group-id->legacy-guid
   "Returns the group legacy guid for the given group concept id."
   [context group-id]
-  (let [cache (c/context->cache context group-cache-key)
-        group-id-to-legacy-guid-map (c/get-value
-                                     cache group-cache-key
-                                     ;; This retrieve is added to make dev repl work
-                                     (partial retrieve-group-id-to-legacy-guid-map context))]
-    (if-let [legacy-guid (get group-id-to-legacy-guid-map group-id)]
-      (cache-value->legacy-guid legacy-guid)
-      ;; legacy-guid does not exist in cache, we retrieve it and add it to the cache.
-      ;; We can do this because once created, group's concept-id and legacy guid will never change.
-      ;; Group will get a new concept id if it is deleted and recreated;
-      ;; Group's legacy guid is not allowed to change when group is updated.
-      (let [legacy-guid (:legacy_guid (group-service/get-group-by-concept-id context group-id))]
-        (c/set-value cache group-cache-key
-                     (assoc group-id-to-legacy-guid-map
-                            group-id
-                            (legacy-guid->cache-value legacy-guid)))
-        legacy-guid))))
+  (let [cache (c/context->cache context group-cache-key)]
+    (c/get-value cache group-id (partial get-group-legacy-guid context group-id))))


More on atoms.

More on atoms.

--- test/com/nomistech/clojure_the_language/intro_to_state.clj
+++ test/com/nomistech/clojure_the_language/intro_to_state.clj
@@ -111,22 +111,28 @@

 (defn demo-competition-to-modify-atom []
   (let [n-attempts-atom (atom 0)]
-    (dotimes [_ n-competitors]
-      (.start (Thread. (fn []
-                         (swap! competing-updates-atom
-                                (fn [n]
-                                  (swap! n-attempts-atom inc)
-                                  (Thread/sleep (rand-int 200))
-                                  (inc n)))))))
-    (loop []
-      (println [@competing-updates-atom
-                @n-attempts-atom])
-      (when (< @competing-updates-atom n-competitors)
-        (Thread/sleep 1000)
-        (recur)))
-    (println "Finished. n-attempts =" @n-attempts-atom)
-    [@competing-updates-atom
-     @n-attempts-atom]))
+    (letfn [(create-competing-threads []
+              (dotimes [_ n-competitors]
+                (.start (Thread. (fn []
+                                   (swap! competing-updates-atom
+                                          (fn [n]
+                                            (swap! n-attempts-atom inc)
+                                            (Thread/sleep (rand-int 200))
+                                            (inc n))))))))
+            (report-on-what-is-happenning []
+              (loop []
+                (println [@competing-updates-atom
+                          @n-attempts-atom])
+                (when (< @competing-updates-atom n-competitors)
+                  (Thread/sleep 1000)
+                  (recur))))
+            (wrap-up-and-result []
+              (println "Finished. n-attempts =" @n-attempts-atom)
+              [@competing-updates-atom
+               @n-attempts-atom])]
+      (create-competing-threads)
+      (report-on-what-is-happenning)
+      (wrap-up-and-result))))

 (fact "About concurrency and atoms"
   (let [[final-value n-attempts] (demo-competition-to-modify-atom)]


CMR-755: Adding test from failed catalog rest integration test.

--- test/cmr/system_int_test/search/collection_spatial_search_test.clj
+++ test/cmr/system_int_test/search/collection_spatial_search_test.clj
@@ -24,6 +24,13 @@

 (use-fixtures :each (ingest/reset-fixture {"provguid1" "PROV1"}))

+(comment
+
+  (ingest/reset)
+  (ingest/create-provider "provguid1" "PROV1")
+
+  )
+
 (defn polygon
   "Creates a single ring polygon with the given ordinates. Points must be in counter clockwise order.
   The polygon will be closed automatically."
@@ -105,6 +112,8 @@
   (let [;; Lines
         normal-line (make-coll :geodetic "normal-line"
                                (l/ords->line-string :geodetic 22.681 -8.839, 18.309 -11.426, 22.705 -6.557))
+        along-am-line (make-coll :geodetic "along-am-line"
+                                 (l/ords->line-string :geodetic -180 0 -180 85))
         normal-line-cart (make-coll :cartesian "normal-line-cart"
                                     (l/ords->line-string :cartesian 16.439 -13.463,  31.904 -13.607, 31.958 -10.401))

@@ -170,10 +179,11 @@
                                                   polygon-with-holes-cart normal-line-cart
                                                   normal-line normal-poly-cart]
            ;; across antimeridian
-           [-167.85,-9.08,171.69,43.24] [whole-world across-am-br across-am-poly very-wide-cart]
+           [-167.85,-9.08,171.69,43.24] [whole-world across-am-br across-am-poly very-wide-cart
+                                         along-am-line]

            ;; across north pole
-           [0 85, 180 85] [whole-world north-pole on-np touches-np]
+           [0 85, 180 85] [whole-world north-pole on-np touches-np along-am-line]

            ;; across north pole where cartesian polygon touches it
            [-155 85, 25 85] [whole-world north-pole on-np very-tall-cart]
@@ -267,7 +277,8 @@
                             polygon-with-holes-cart]

            ;; crosses am
-           [166.11,53.04,-166.52,-19.14] [whole-world across-am-poly across-am-br am-point very-wide-cart]
+           [166.11,53.04,-166.52,-19.14] [whole-world across-am-poly across-am-br am-point
+                                          very-wide-cart along-am-line]

            ;; Matches geodetic line
            [17.67,-4,25.56,-6.94] [whole-world normal-line]
@@ -280,7 +291,8 @@
                               wide-north wide-south across-am-poly on-sp on-np normal-poly
                               polygon-with-holes north-pole south-pole normal-point am-point
                               very-wide-cart very-tall-cart wide-north-cart wide-south-cart
-                              normal-poly-cart polygon-with-holes-cart normal-line normal-line-cart]))
+                              normal-poly-cart polygon-with-holes-cart normal-line normal-line-cart
+                              along-am-line]))

     (testing "polygon searches"
       (are [ords items]
@@ -303,7 +315,7 @@

            ;; around north pole
            [58.41,76.95,163.98,80.56,-122.99,81.94,-26.18,82.82,58.41,76.95]
-           [whole-world on-np touches-np north-pole very-tall-cart]
+           [whole-world on-np touches-np north-pole very-tall-cart along-am-line]

            ;; around south pole
            [-161.53,-69.93,25.43,-51.08,13.89,-39.94,-2.02,-40.67,-161.53,-69.93]
@@ -311,7 +323,7 @@

            ;; Across antimeridian
            [-163.9,49.6,171.51,53.82,166.96,-11.32,-168.36,-14.86,-163.9,49.6]
-           [whole-world across-am-poly across-am-br am-point very-wide-cart]
+           [whole-world across-am-poly across-am-br am-point very-wide-cart along-am-line]

            [-2.212 -12.44, 0.103 -15.911, 2.185 -11.161 -2.212 -12.44]
            [whole-world normal-poly-cart polygon-with-holes-cart]
@@ -371,9 +383,18 @@
            [whole-world normal-poly normal-brs polygon-with-holes normal-line normal-line-cart]

            :box [23.59,-4,25.56,-15.47] [whole-world normal-line-cart]
+
+           ;; Across antimeridian
+           :box [170 20 -170 10]
+           [whole-world across-am-br along-am-line]
+
+           :box [166.11,53.04,-166.52,-19.14]
+           [whole-world across-am-poly across-am-br am-point very-wide-cart along-am-line]
+
            :point [17.73 2.21] [whole-world normal-brs]
            :line [-0.37,-14.07,4.75,1.27,25.13,-15.51]
            [whole-world polygon-with-holes polygon-with-holes-cart normal-line-cart normal-line
             normal-poly-cart]))))

+


Update neko

Update neko

--- src/clojure/leiningen/new/game_clojure/android-project.clj
+++ src/clojure/leiningen/new/game_clojure/android-project.clj
@@ -3,7 +3,7 @@

   :dependencies [[com.badlogicgames.gdx/gdx "0.9.9" :use-resources true]
                  [com.badlogicgames.gdx/gdx-backend-android "0.9.9"]
-                 [neko/neko "3.0.0-preview4"]
+                 [neko/neko "3.0.0"]
                  [org.clojure-android/clojure "1.5.1-jb" :use-resources true]]
   :repositories [["sonatype"
                   "https://oss.sonatype.org/content/repositories/snapshots/"]]


Change some CC links to https

Change some CC links to https

--- src/langnostic/pages.clj
+++ src/langnostic/pages.clj
@@ -61,12 +61,12 @@
   [:div {:class "license"}
    [:a {:rel "license" :href "http://creativecommons.org/licenses/by-sa/3.0/"}
     [:img {:alt "Creative Commons License" :style "border-width:0;float: left; margin: 0px 15px 15px 0px;"
-           :src "http://i.creativecommons.org/l/by-sa/3.0/88x31.png"}]]
+           :src "https://i.creativecommons.org/l/by-sa/3.0/88x31.png"}]]
    [:p
-    [:span {:xmlns:dct "http://purl.org/dc/terms/" :property "dct:title"}
+    [:span {:xmlns:dct "https://purl.org/dc/terms/" :property "dct:title"}
      "all articles at langnostic"]
     " are licensed under a "
-    [:a {:rel "license" :href "http://creativecommons.org/licenses/by-sa/3.0/"}
+    [:a {:rel "license" :href "https://creativecommons.org/licenses/by-sa/3.0/"}
      "Creative Commons Attribution-ShareAlike 3.0 Unported License"]]
    [:p
     "Reprint, rehost and distribute freely (even for profit), but attribute the work and allow your readers the same freedoms. "


CMR-2501: Added a simple test.

CMR-2501: Added a simple test.

--- system-int-test/test/cmr/system_int_test/search/tagging/tag_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/tagging/tag_search_test.clj
@@ -3,6 +3,7 @@
   (:require [clojure.test :refer :all]
             [clojure.string :as str]
             [cmr.common.util :refer [are2]]
+            [cmr.common.mime-types :as mt]
             [cmr.system-int-test.utils.ingest-util :as ingest]
             [cmr.system-int-test.utils.search-util :as search]
             [cmr.system-int-test.utils.index-util :as index]
@@ -136,3 +137,17 @@
       ;; Now I should find the tag when searching
       (tags/assert-tag-search [tag1-3 tag2] (tags/search {})))))

+(deftest retrieve-tags-by-concept-id-test
+  (let [user1-token (e/login (s/context) "user1")
+        tag1 (tags/save-tag user1-token (tags/make-tag {:tag-key "tag1"}))
+        tag2 (tags/save-tag user1-token (tags/make-tag {:tag-key "tag2"}))
+        all-tags [tag1 tag2]]
+    (index/wait-until-indexed)
+
+    ;; CMR-2580 will add more tests on retrieving tags by concept-id,
+    ;; here we just make sure the status is 200.
+    (testing "retrieval by tag concept-id returns the latest revision."
+      (let [{:keys [status]} (search/retrieve-concept
+                               (:concept-id tag1) nil {:accept mt/xml})]
+        (is (= 200 status))))))
+


Make logstash machine coreos

Make logstash machine coreos

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -2,30 +2,66 @@
   (:require [terraboot.core :refer :all]
             [terraboot.utils :refer :all]
             [terraboot.cloud-config :refer [cloud-config]]
-            [cheshire.core :as json]))
-
-(def logstash-user-data (cloud-config {:package_update true
-                                       :bootcmd ["echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections"
-                                                 "wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | apt-key add -" ]
-                                       :apt_sources [{:source "ppa:webupd8team/java"}
-                                                     {:source "deb http://packages.elastic.co/logstash/2.3/debian stable main"
-                                                      :key (snippet "system-files/elasticsearch-apt.pem")}]
-                                       :packages ["oracle-java8-installer"
-                                                  "oracle-java8-set-default"
-                                                  "logstash"]
-                                       :runcmd ["update-rc.d logstash defaults"]
-                                       :write_files [{:path "/etc/logstash/conf.d/out-es.conf"
-                                                      :permissions "644"
-                                                      :content (snippet "vpc-logstash/out-es.conf")}
-                                                     {:path "/etc/logstash/conf.d/in-beats.conf"
-                                                      :permissions "644"
-                                                      :content (snippet "vpc-logstash/in-beats.conf")}
-                                                     {:path "/etc/logstash/conf.d/in-gelf.conf"
-                                                      :permissions "644"
-                                                      :content (snippet "vpc-logstash/in-gelf.conf")}
-                                                     {:path "/opt/logstash/patterns/basic-batterns"
-                                                      :permissions "644"
-                                                      :content (snippet "vpc-logstash/basic-patterns")}]}))
+            [cheshire.core :as json]
+            [clojure.string :as str]
+            [clojure.core.strint :refer [<<]]))
+
+(def logshipper "")
+
+(def stop-update-engine {:name "update-engine.service"
+                         :command "stop"})
+
+(def stop-locksmithd {:name "locksmithd.service"
+                      :command "stop"})
+
+(def common-coreos-units [stop-update-engine
+                          stop-locksmithd])
+
+(defn docker-systemd-unit
+  ([org-name image-name] (docker-systemd-unit org-name image-name {}))
+  ([org-name image-name {options :options
+                         entry-point :entry-point
+                         release :release
+                         :or {options []
+                              entry-point ""
+                              release "latest"}}]
+   (let [option-string (str/join " " options)
+         full-image-name (str org-name "/" image-name)]
+     {:name (str image-name ".service")
+      :command "start"
+      :enable true
+      :content (<<
+                "[Unit]
+Description=~{image-name}
+After=docker.service
+Requires=docker.service
+
+[Service]
+Slice=machine.slice
+TimeoutSec=600
+ExecStartPre=/usr/bin/docker pull ~{full-image-name}:~{release}
+ExecStartPre=-/usr/bin/docker kill ~{image-name}
+ExecStartPre=-/usr/bin/docker rm ~{image-name}
+ExecStart=/usr/bin/docker run --name ~{image-name} ~{option-string} ~{full-image-name}:~{release} ~{entry-point}
+ExecStop=/usr/bin/docker stop ~{image-name}
+
+[Install]
+WantedBy=multi-user.target")})))
+
+(defn cloud-config-coreos [units]
+  (cloud-config {:coreos {:update
+                          {:reboot-strategy "off"}
+                          :units (concat common-coreos-units
+                                         units)
+                          }}))
+
+(defn logstash-user-data-coreos [es-host]
+  (let [run-logstash (docker-systemd-unit "mastodonc" "logstash-ng"
+                                          {:options [(str "--env " "ES_HOST=" es-host)
+                                                     "--net=host"]
+                                           :entry-point "-f /etc/logstash/logstash.conf"}
+                                          )]
+    (cloud-config-coreos [run-logstash])))

 (defn elasticsearch-policy
   []
@@ -50,19 +86,21 @@
         vpc-id-of (id-of-fn vpc-unique)
         vpc-output-of (output-of-fn vpc-unique)
         vpc-security-group (partial scoped-security-group vpc-unique)
-        elb-listener (account-elb-listener account-number
-                                           )]
+        elb-listener (account-elb-listener account-number)
+        es-arn (str "arn:aws:es:" region ":" account-number ":domain/" vpc-name "-elasticsearch-5")
+        es-arn-* (str es-arn "/*")]
+
     (merge-in
-     (template-file (vpc-unique "elasticearch-policy")
+     (template-file (vpc-unique "elasticsearch-policy")
                     (elasticsearch-policy)
-                    {:es-arn (str "arn:aws:es:" region ":" account-number ":domain/" vpc-name "-elasticsearch/*")
-                     :allowed-ips  (vpc-output-of "aws_eip" "logstash" "public_ip")})
-
-     (vpc-resource "aws_elasticsearch_domain" name
-                   {:domain_name (vpc-unique name)
-                    :advanced_options { "rest.action.multi.allow_explicit_index" true}
-                    :access_policies ""#_(rendered-template-file (vpc-unique "elasticsearch-policy"))
-
+                    {:es-arn es-arn-*
+                     :allowed-ips  (vpc-output-of "aws_eip" "vpn" "public_ip")})
+
+     (vpc-resource "aws_elasticsearch_domain" (str (vpc-unique name) "-5")
+                   {:domain_name (str (vpc-unique name) "-5")
+                    :elasticsearch_version "5.1"
+                    :advanced_options { "rest.action.multi.allow_explicit_index" "true"}
+                    :access_policies (rendered-template-file (vpc-unique "elasticsearch-policy"))
                     :cluster_config {:instance_count 2,
                                      :instance_type "t2.small.elasticsearch"}
                     :ebs_options {:ebs_enabled true,
@@ -70,6 +108,41 @@
                                   :volume_size 35
                                   },
                     :snapshot_options { :automated_snapshot_start_hour 23}})
+
+     (vpc-resource "aws_iam_role" "logstash" {:name "logstash"
+                                              :assume_role_policy (json/generate-string {
+                                                                                "Version" "2012-10-17",
+                                                                                "Statement" [
+                                                                                {
+                                                                                "Action" "sts:AssumeRole",
+                                                                                "Principal" {
+                                                                                "Service" "ec2.amazonaws.com"
+                                                                                },
+                                                                                "Effect" "Allow",
+                                                                                "Sid" ""}]})})
+
+     (vpc-resource "aws_iam_role_policy" "logstash"
+                   {"name" "logstash"
+                    "role"  (vpc-id-of "aws_iam_role" "logstash")
+                    "policy" (json/generate-string {
+                                                    "Version" "2012-10-17"
+                                                    "Statement" [{
+                                                                  "Resource" es-arn-*,
+                                                                  "Action" ["es:*"],
+                                                                  "Effect" "Allow"
+                                                                  }
+                                                                 {
+                                                                  "Resource" es-arn,
+                                                                  "Action" ["es:*"],
+                                                                  "Effect" "Allow"
+                                                                  }
+                                                                 ]})})
+
+     (vpc-resource "aws_iam_instance_profile" "logstash" {
+                                                          :name "logstash"
+                                                          :roles  [(vpc-output-of "aws_iam_role" "logstash" "name")]
+                                                          })
+
      (add-key-name-to-instances
       key-name
       (in-vpc (id-of "aws_vpc" vpc-name)
@@ -91,26 +164,21 @@
                             {:vpc true
                              :instance (vpc-id-of "aws_instance" "logstash")})

-
               (vpc-security-group "sends_gelf" {})

               (vpc-security-group "sends_logstash" {})

-              (template-file (vpc-unique "logstash-user-data")
-                             logstash-user-data
-                             {:es-dns (vpc-output-of "aws_elasticsearch_domain" name "endpoint")})
-
-              (aws-instance (vpc-unique "logstash") {:ami default-ami
+              (aws-instance (vpc-unique "logstash") {:ami "ami-2cb14043"
                                                      :instance_type "m4.large"
                                                      :vpc_security_group_ids [(vpc-id-of "aws_security_group" "logstash")
                                                                               (id-of "aws_security_group" "allow_ssh")
                                                                               (vpc-id-of "aws_security_group" "sends_influx")
                                                                               (vpc-id-of "aws_security_group" "all-servers")
                                                                               ]
-                                                     :user_data (rendered-template-file (vpc-unique "logstash-user-data"))
+                                                     :user_data (logstash-user-data-coreos (vpc-output-of "aws_elasticsearch_domain" (str (vpc-unique name) "-5") "endpoint"))
                                                      :associate_public_ip_address true
                                                      :subnet_id (vpc-id-of "aws_subnet" "public-a")
-                                                     })
+                                                     :iam_instance_profile (vpc-id-of "aws_iam_instance_profile" "logstash")})

               (aws-instance (vpc-unique "kibana") {
                                                    :ami default-ami
@@ -121,7 +189,6 @@
                                                    :subnet_id (vpc-id-of "aws_subnet" "private-a")
                                                    :associate_public_ip_address true
                                                    })
-

               (elb "kibana" resource {:name "kibana"
                                       :health_check {:healthy_threshold 2
@@ -144,7 +211,6 @@
               ;; alerting server needs access to all servers
               (vpc-security-group "nrpe" {})

-
               (database {:name (vpc-unique "alerts")
                          :subnet vpc-name})


Story ID: develop Summary: - fix for om/mock-root deprecation in data-fetch-spec

--- spec/untangled/client/data_fetch_spec.cljs
+++ spec/untangled/client/data_fetch_spec.cljs
@@ -127,7 +127,7 @@
         reconciler (om/reconciler {:state      state-tree
                                    :merge-tree util/deep-merge
                                    :parser     (om/parser {:read (constantly nil)})})
-        _ (om/mock-root reconciler PanelRoot)
+        _ (om/add-root! reconciler PanelRoot "invisible-specs")
         state (om/app-state reconciler)]

     (when-mocking


insights: add legend to chart

insights: add legend to chart

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -66,6 +66,19 @@
                     (.domain (clj->js
                               (map :build_num builds)))
                     (.rangeBands #js[0 width] 0.5))
+        legend-dimensions {:square-size 10
+                           :item-width 80
+                           :item-height 14   ; assume font is 14px
+                           :spacing 4
+                           }
+        left-legend [{:class "success"
+                      :text "Passed"}
+                     {:class "failed"
+                      :text "Failed"}
+                     {:class "canceled"
+                      :text "Canceled"}]
+        right-legend [{:class "queue"
+                      :text "Queue time"}]
         svg (-> js/d3
                 (.select elem)
                 (.html "")
@@ -83,6 +96,65 @@
         grid-lines-container (-> svg
                                  (.append "g")
                                  (.attr "class" "grid-line horizontal"))]
+    ;; left legend
+    (let [{:keys [square-size item-width item-height spacing]} legend-dimensions
+          legend-item (-> svg
+                          (.selectAll ".legend")
+                          (.data (clj->js left-legend))
+                          (.enter)
+                          (.append "g")
+                          (.attr #js {"class" "legend left"
+                                      "transform"
+                                      (fn [item i]
+                                        (let [tr-x (* i item-width)
+                                              tr-y (- (- item-height
+                                                         (/ (- item-height square-size)
+                                                            2)))]
+                                          (gstring/format "translate(%s,%s)" tr-x  tr-y)))}))]
+      (-> legend-item
+          (.append "rect")
+          (.attr #js {"width" (:square-size legend-dimensions)
+                      "height" (:square-size legend-dimensions)
+                      "class" #(.-class %)
+                      "transform"
+                      (fn [item i]
+                        (gstring/format "translate(%s,%s)" 0  (- (+ (:square-size legend-dimensions)))))}))
+      (-> legend-item
+          (.append "text")
+          (.attr #js {"x" (+ (:square-size legend-dimensions)
+                             (:spacing legend-dimensions))})
+          (.text #(.-text %))))
+
+    ;; right legend
+    (let [{:keys [square-size item-width item-height spacing]} legend-dimensions
+          legend-item (-> svg
+                          (.selectAll ".legend-right")
+                          (.data (clj->js right-legend))
+                          (.enter)
+                          (.append "g")
+                          (.attr #js {"class" "legend right"
+                                      "transform"
+                                      (fn [item i]
+                                        (let [tr-x (- width (* (inc i) item-width))
+                                              tr-y (- (- item-height
+                                                         (/ (- item-height square-size)
+                                                            2)))]
+                                          (gstring/format "translate(%s,%s)" tr-x  tr-y)))}))]
+      (-> legend-item
+          (.append "rect")
+          (.attr #js {"width" (:square-size legend-dimensions)
+                      "height" (:square-size legend-dimensions)
+                      "class" #(.-class %)
+                      "transform"
+                      (fn [item i]
+                        (gstring/format "translate(%s,%s)" 0  (- (+ (:square-size legend-dimensions)))))}))
+      (-> legend-item
+          (.append "text")
+          (.attr #js {"x" (+ (:square-size legend-dimensions)
+                             (:spacing legend-dimensions))})
+          (.text #(.-text %))))
+
+
     ;; y-axis
     (-> svg
         (.append "g")


Update transcode.clj

Update transcode.clj

remove todo

--- src/unicodify_clj/transcode.clj
+++ src/unicodify_clj/transcode.clj
@@ -127,8 +127,3 @@
                         fix-ra-anusvara)]
     (print-ascii-chars-found unicodified)
     unicodified))
-
-
-;; todo:
-;; line 80 in aavanchit
-;; no transcode in the ghazals


Revert "Remove `update-radius-attrs` event."

This reverts commit b1e9936aa6552bde75e9c7ffb0bcdfeedc98be56.

--- src/uxbox/main/data/shapes.cljs
+++ src/uxbox/main/data/shapes.cljs
@@ -237,6 +237,17 @@
                  (when color {:stroke color})
                  (when opacity {:stroke-opacity opacity})))))

+(defn update-radius-attrs
+  [sid {:keys [rx ry] :as opts}]
+  (reify
+    udp/IPageUpdate
+    rs/UpdateEvent
+    (-apply-update [_ state]
+      (update-in state [:shapes-by-id sid]
+                 merge
+                 (when rx {:rx rx})
+                 (when ry {:ry ry})))))
+
 (defn hide-shape
   [sid]
   (reify


(concepts :vychodil ctx) does not use generators anymore

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@tu-dresden.de>

--- src/main/clojure/conexp/contrib/algorithms/concepts.clj
+++ src/main/clojure/conexp/contrib/algorithms/concepts.clj
@@ -16,6 +16,7 @@
                                             incidence, attribute-derivation,
                                             context-attribute-closure)])
 (require '[conexp.contrib.algorithms.close-by-one :as cbo])
+(require '[clojure.core.async :refer (thread >!! <!! chan close!)])
 (import '[java.util BitSet List ArrayList])
 (import '[java.util.concurrent SynchronousQueue])

@@ -88,9 +89,9 @@
           (.set D j false))))
     [C, D]))

-(defg vychodil-generate-from
-  [object-count, attribute-count, incidence-matrix, rows, ^BitSet A, ^BitSet B, y]
-  (yield [A, B])
+(defn vychodil-generate-from
+  [output, object-count, attribute-count, incidence-matrix, rows, ^BitSet A, ^BitSet B, y]
+  (>!! output [A, B])
   (when (and (not (== attribute-count (.cardinality B)))
              (< (int y) (int attribute-count)))
     (doseq [j (range (int y) (int attribute-count))
@@ -104,7 +105,8 @@
                            (not= (.get D k) (.get B k)) true,
                            :else (recur (inc k))))]
             :when (not skip)]
-      (vychodil-generate-from object-count attribute-count,
+      (vychodil-generate-from output
+                              object-count attribute-count,
                               incidence-matrix rows,
                               C D (inc j)))))

@@ -128,17 +130,22 @@
           empty-down-up (bitwise-object-derivation incidence-matrix
                                                    object-count
                                                    attribute-count
-                                                   empty-down)]
+                                                   empty-down)
+          output        (chan)]
+      (thread (vychodil-generate-from output
+                                      object-count
+                                      attribute-count
+                                      incidence-matrix
+                                      rows
+                                      empty-down
+                                      empty-down-up
+                                      0)
+              (close! output))
       (map (fn [pair]
              [(to-hashset object-vector (first pair))
               (to-hashset attribute-vector (second pair))])
-           (generate (vychodil-generate-from object-count
-                                             attribute-count
-                                             incidence-matrix
-                                             rows
-                                             empty-down
-                                             empty-down-up
-                                             0))))))
+           (take-while (comp not nil?)
+                       (repeatedly #(<!! output)))))))

 ;;; In-Close (:in-close)


make sure id-sk,id-sk-origin is unique

make sure id-sk,id-sk-origin is unique

--- src/navigator/schema.clj
+++ src/navigator/schema.clj
@@ -32,7 +32,8 @@
                         [:comps :ref :many]
                         [:credit-value-numerator :bigint]
                         [:credit-value-denominator :bigint]]
-               :dbfns [(constraints/unique :perf-asmt :name :version :type)]}]
+               :dbfns [(constraints/unique :perf-asmt :name :version :type)
+                       (constraints/unique :perf-asmt :id-sk :id-sk-origin)]}]
    [:task {:attrs [[:id-sk :string]
                    [:id-sk-origin :keyword] ; e.g., :moodle, :show-evidence, etc.
                    [:name :string]
@@ -40,7 +41,8 @@
                    [:description :string]

                    ;; TODO: is this correct?
-                   [:comps :ref :many]]}]
+                   [:comps :ref :many]]
+           :dbfns [(constraints/unique :perf-asmt :id-sk :id-sk-origin)]}]
    [:user2comp {:attrs [[:sis-user-id :bigint :indexed]
                         [:comp :ref :indexed]
                         [:start-date :instant]


Use next-send instead of :start-date.

Use next-send instead of :start-date.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -500,7 +500,7 @@
   (str (first-name (:author reminder-data)) " created a new reminder for you"))

 (defn reminder-notification-subline [reminder-data]
-  (str (:frequency reminder-data) " starting " (post-date (:start-date reminder-data))))
+  (str (:frequency reminder-data) " starting " (post-date (:next-send reminder-data))))

 (def reminder-notification-settings-footer
   [:table {:class "row reminders-footer"


Fix url compose for notifications.

Fix url compose for notifications.

Use org or board slug and fallback to the uuid, get the parts from the notification or the board/org map or from the entry data if possible.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -635,9 +635,14 @@
   (let [notification (:notification msg)
         content (:content notification)
         org (:org msg)
+        board (:board msg)
         entry-data (:entry-data notification)
-        board-slug (:board-slug entry-data)
         org-slug (:slug org)
+        org-uuid (or (:uuid org) (:org-uuid entry-data) (:org-id notification))
+        org-url-part (or org-slug org-uuid)
+        board-slug (or (:board-slug entry-data) (:slug board))
+        board-uuid (or (:board-uuid entry-data) (:uuid board) (:board-id notification))
+        board-url-part (or board-slug board-uuid)
         mention? (:mention notification)
         interaction-id (:interaction-id notification)
         first-name (:first-name msg)
@@ -645,8 +650,8 @@
         notification-author (:author notification)
         is-default-avatar? (s/starts-with? (:avatar-url notification-author) "/img")
         notification-author-url (user-lib/fix-avatar-url config/filestack-api-key (:avatar-url notification-author) 128)
-        uuid (:entry-id notification)
-        secure-uuid (:secure-uuid notification)
+        entry-uuid (or (:entry-id notification) (:uuid entry-data))
+        secure-uuid (or (:secure-uuid notification) (:secure-uuid entry-data))
         origin-url config/web-url
         token-claims {:org-uuid (:org-id notification)
                       :secure-uuid secure-uuid
@@ -657,10 +662,12 @@
                       :avatar-url (:avatar-url msg)
                       :team-id (:team-id org)} ;; Let's read the team-id from the org to avoid problems on multiple org users
         id-token (jwt/generate-id-token token-claims config/passphrase)
-        base-url (if (seq interaction-id)
-                   (s/join "/" [origin-url org-slug board-slug "post" uuid "comment" interaction-id])
-                   (s/join "/" [origin-url org-slug board-slug "post" uuid]))
-        entry-url (str base-url "?id=" id-token)
+        url-parts (cond-> [origin-url org-url-part]
+                    board-url-part (conj board-url-part)
+                    entry-uuid (concat ["post" entry-uuid])
+                    interaction-id (concat ["comment" interaction-id]))
+        base-url (s/join "/" url-parts)
+        final-url (str base-url "?id=" id-token)
         button-cta (if (or (not mention?) interaction-id)
                     "view_comment"
                     "view_post")
@@ -675,13 +682,13 @@
         (spacer 24))
       (h1 intro)
       (spacer 8)
-      (h2 (:headline post-data) entry-url)
+      (h2 (:headline post-data) final-url)
       (spacer 24)
       (spacer 24 "note-paragraph top-note-paragraph" "note-paragraph top-note-paragraph")
       (paragraph notification-html-content "note-paragraph note-left-padding" "text-left" "note-x-margin")
       (spacer 24 "note-paragraph bottom-note-paragraph" "note-paragraph bottom-note-paragraph")
       (spacer 24)
-      (left-button button-cta entry-url)
+      (left-button button-cta final-url)
       (spacer 40)]))

 (defn- notify-team-content [msg]


Improve error message when passphrase or key absent

--- auth/src/com/sixsq/slipstream/auth/simple_authentication.clj
+++ auth/src/com/sixsq/slipstream/auth/simple_authentication.clj
@@ -41,15 +41,18 @@

 (defn private-key
   [auth-conf]
-  (if-let [passphrase (environ/env :passphrase)]
-    (ks/private-key
-      (io/resource (:privkey auth-conf))
-      passphrase)
-    (throw (IllegalStateException. "passphrase not defined"))))
+  (let [passphrase (environ/env :passphrase)
+        privkey    (io/resource (:privkey auth-conf))]
+    (if (and passphrase privkey)
+      (ks/private-key privkey passphrase)
+      (throw (IllegalStateException. "Passphrase not defined or private key not accessible (must be in the classpath).")))))

 (defn public-key
   [auth-conf]
-  (ks/public-key (io/resource (:pubkey auth-conf))))
+  (let [pubkey (io/resource (:pubkey auth-conf))]
+    (if pubkey
+      (ks/public-key pubkey)
+      (throw (IllegalStateException. "Public key not accessible (must be in the classpath).")))))

 (defn init
   []


Korjaa NPE jos playoff-kierroksia ei ole

--- mtg-pairings-server/src/clj/mtg_pairings_server/service/tournament.clj
+++ mtg-pairings-server/src/clj/mtg_pairings_server/service/tournament.clj
@@ -576,18 +576,17 @@
       bracket)))

 (defn bracket [tournament-id]
-  (let [playoff-rounds (sql/select db/round
-                         (sql/fields :id :num)
-                         (sql/where {:tournament tournament-id
-                                     :playoff    true})
-                         (sql/order :num :DESC))
-        final-standings (standings tournament-id (dec (:num (last playoff-rounds))) false)
-        team->rank (into {} (map (juxt :team :rank)) final-standings)
-        playoff-matches (map (comp (partial add-ranks team->rank)
-                                   results-of-round
-                                   :id)
-                             playoff-rounds)]
-    (when (seq playoff-matches)
+  (when-let [playoff-rounds (seq (sql/select db/round
+                                   (sql/fields :id :num)
+                                   (sql/where {:tournament tournament-id
+                                               :playoff    true})
+                                   (sql/order :num :DESC)))]
+    (let [final-standings (standings tournament-id (dec (:num (last playoff-rounds))) false)
+          team->rank (into {} (map (juxt :team :rank)) final-standings)
+          playoff-matches (map (comp (partial add-ranks team->rank)
+                                     results-of-round
+                                     :id)
+                               playoff-rounds)]
       (loop [acc (take 1 playoff-matches)
              [current-matches & rounds] (rest playoff-matches)]
         (if current-matches


Add a cancel button

Add a cancel button

--- src/braid/core/client/ui/views/thread.cljs
+++ src/braid/core/client/ui/views/thread.cljs
@@ -127,7 +127,9 @@
                (for [user @users]
                  ^{:key (user :id)}
                  [user-option-view user (thread :id) (= user @selected)]))
-             [:div.name "No unmentioned users matching"])]]]))))
+             [:div.name "No unmentioned users matching"])]]
+
+         [:button.cancel {:on-click (fn [_] (popovers/close!))} "Cancel"]]))))

 (defn add-tag-button-view [thread]
   [:div.add


Cassandra client lifecycle implementation done

--- src/clj/hellhound/components/cassandra.clj
+++ src/clj/hellhound/components/cassandra.clj
@@ -6,6 +6,7 @@
    [environ.core                   :as environ]
    [qbits.alia                     :as alia]
    [qbits.hayt                     :as hayt]
+
    ;; Internals
    [hellhound.components.protocols :as protocols]
    [hellhound.logger.core          :as logger]
@@ -27,30 +28,47 @@
 (defn- check-session
   [session name]
   (if (nil? session)
-    (throw (Exception. (format "'%s' component is not started yet." name)))))
+    (throw (ex-info
+            (format "'%s' component is not started yet." name)
+            {:cause "Cassandra component"}))))
+
+(defn select-keyspace
+  [session keyspace]
+  (try
+    (alia/execute session (format "USE %s;" keyspace))
+    (catch clojure.lang.ExceptionInfo e
+      (throw
+       (ex-info "Keyspace is not present. You need to migrate first." {})))))

 (defrecord Cassandra [options]
-  protocols/DatabaseLifecycle
+
+  ;; Lifecycle implementation.
+  protocols/Lifecycle

   (start [this]
+    ;; Validate Configuration
     (spec/valid? ::cassanda-configuration options)
+
     (logger/info "Connecting to Cassandra cluster...")
+
+    ;; Connect to the cluster and select the default keyspace
     (let [session   (connect options)
           keyspace  (:name (:keyspace options))]
-
-      (try
-        (alia/execute session (format "USE %s;" keyspace))
-        (catch  com.datastax.driver.core.exceptions.InvalidQueryException e
-          (throw (Exception. "Keyspace is not present. You need to migrate first."))))
+      (select-keyspace session keyspace)
       (assoc this :session session :keyspace keyspace)))

   (stop [this]
     (if (:session this)
       (do
         (logger/info "Disconnecting from Cassandra cluster...")
+        ;; Shutting down the connection to cluster
         (alia/shutdown (:session this))
-        (dissoc this :session :keyspace :keyspace-selected))
+        (dissoc this :session :keyspace :keyspace))
       this))
+
+  ;; DatabaseLifecycle implementation. Allow the migration system to operate
+  ;; with this component
+  protocols/DatabaseLifecycle

   (setup [this]
     (let [session (:session this)]
@@ -77,11 +95,11 @@
    (let [config (merge (cassandra-config) options)]
      (->Cassandra config))))

-(defn cassandra-client
+(defn new-cassandra-client
   "Create an instance from cassandra component. This function is meant
   to be used with `hellhound.system.defsystem` macro."
   ([system-map]
-   (cassandra-client system-map {}))
+   (new-cassandra-client system-map {}))
   ([system-map options]
    (let [config (merge (cassandra-config) options)]
      (update-in system-map [:components :cassandra] (->Cassandra config)))))


Implemented restful route for getting contents of an example specification.

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -24,8 +24,13 @@
                       (files-as-list example-dir))]
     {:body (zipmap filelist (map filename-as-text filelist))}))

+(defn example-file
+  [filename]
+  {:body {:contents (slurp (str example-dir "/" filename))}})
+
 (defroutes api-routes
-  (GET "/api/examples" [] (example-listing)))
+  (GET "/api/examples" [] (example-listing))
+  (GET "/api/examples/:filename" [filename] (example-file filename)))

 (defn index
   [req]


CW + CM | #122 | validations for posting annotation

--- test/objective8/integration/front_end/validations.clj
+++ test/objective8/integration/front_end/validations.clj
@@ -258,9 +258,14 @@
             (fact "validation errors are reported when posting a comment on a draft section"
                   (-> user-session
                       ih/sign-in-as-existing-user
-                      (p/request (utils/path-for :fe/post-comment)
+                      (p/request (utils/path-for :fe/post-annotation
+                                                 :id OBJECTIVE_ID
+                                                 :d-id DRAFT_ID
+                                                 :section-label SECTION_LABEL)
+
                                  :request-method :post
                                  :params {:comment ?comment
+                                          :reason "general"
                                           :comment-on-uri "/thing/to/comment/on"
                                           :refer (utils/local-path-for :fe/draft-section
                                                                        :id OBJECTIVE_ID
@@ -270,7 +275,7 @@
                       :response
                       :body) => (contains ?error-tag))

-            (fact "comment validation errors are hidden by default on draft view pages"
+            (fact "comment validation errors are hidden by default on draft section pages"
                   (let [draft-section-html (-> user-session
                                        ih/sign-in-as-existing-user
                                        (p/request (utils/path-for :fe/draft-section


Augmented test for trusted facts

Augmented test for trusted facts

--- test/puppetlabs/master/certificate_authority_test.clj
+++ test/puppetlabs/master/certificate_authority_test.clj
@@ -631,6 +631,8 @@

     (testing "trusted fact extensions are properly unfiltered"
       (let [csr-exts [(utils/puppet-node-image-name "imagename" false)
+                      (utils/puppet-node-preshared-key "key" false)
+                      (utils/puppet-node-instance-id "instance" false)
                       (utils/puppet-node-uid "UUUU-IIIII-DDD" false)]
             csr      (utils/generate-certificate-request
                        subject-keys subject-dn csr-exts)
@@ -654,13 +656,20 @@
                            {:oid "2.5.29.14"
                             :critical false
                             :value subject-pub}
+                           {:oid      "1.3.6.1.4.1.34380.1.1.1"
+                            :critical false
+                            :value    "UUUU-IIIII-DDD"}
+                           {:oid      "1.3.6.1.4.1.34380.1.1.2"
+                            :critical false
+                            :value    "instance"}
                            {:oid      "1.3.6.1.4.1.34380.1.1.3"
                             :critical false
                             :value    "imagename"}
-                           {:oid      "1.3.6.1.4.1.34380.1.1.1"
-                            :critical false
-                            :value    "UUUU-IIIII-DDD"}]]
-        (is (= exts exts-expected "The puppet trusted facts extenions were not added by create-agent-extensions"))))
+                           {:oid      "1.3.6.1.4.1.34380.1.1.4"
+                            :critical false
+                            :value    "key"}]]
+        (is (= (set exts) (set exts-expected))
+            "The puppet trusted facts extensions were not added by create-agent-extensions")))

     (testing "only puppet extensions are extracted from CSR and DNS alt names is ignored."
       (let [csr-exts           [(utils/subject-dns-alt-names


Use find-first

Use find-first

--- resources/isometric-rpg/core.clj
+++ resources/isometric-rpg/core.clj
@@ -49,7 +49,7 @@
                        (animate screen)
                        (prevent-move screen entities)
                        (adjust screen))))
-           (attack screen (some #(if (can-attack? % me) %) entities) me)
+           (attack screen (find-first #(can-attack? % me) entities) me)
            (play-sounds!)
            (render! screen)
            (render-sorted! screen ["things"])


CMR-2167: Added namespace to function

CMR-2167: Added namespace to function

--- metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/tag_save_test.clj
+++ metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/tag_save_test.clj
@@ -18,7 +18,7 @@

 (use-fixtures :each (util/reset-database-fixture {:provider-id "REG_PROV" :small false}))

-(defmethod gen-concept :tag
+(defmethod c-spec/gen-concept :tag
   [_ _ uniq-num attributes]
   (util/tag-concept uniq-num attributes))


Added accepted response

Added accepted response

--- dropwizard-clojure-core/src/clojure/dropwizard_clojure/response.clj
+++ dropwizard-clojure-core/src/clojure/dropwizard_clojure/response.clj
@@ -1,9 +1,13 @@
-(ns dropwizard-clojure.response)
+(ns dropwizard-clojure.response
+  (:import (javax.ws.rs.core Response)))

 (defn ok []
-  (.build (javax.ws.rs.core.Response/ok)))
+  (.build (Response/ok)))

 (defn notFound []
-  (.build (.type (javax.ws.rs.core.Response/status 404) javax.ws.rs.core.MediaType/APPLICATION_JSON_TYPE)))
+  (.build (.type (Response/status 404) javax.ws.rs.core.MediaType/APPLICATION_JSON_TYPE)))
+
+(defn accepted []
+  (.build (Response/accepted)))


CMR-1375: Adding up and down to comment

CMR-1375: Adding up and down to comment

--- metadata-db-app/src/migrations/012_add_sync_delete_work_indexes.clj
+++ metadata-db-app/src/migrations/012_add_sync_delete_work_indexes.clj
@@ -4,12 +4,12 @@

 (defn up
   []
-  (println "migrations.012-add-sync-delete-work-indexes")
+  (println "migrations.012-add-sync-delete-work-indexes up")
   (h/sql "CREATE INDEX sdw_cid_rid ON sync_delete_work(concept_id, revision_id)")
   (h/sql "CREATE INDEX sdw_deleted ON sync_delete_work(deleted)"))

 (defn down
   []
-  (println "migrations.012-add-sync-delete-work-indexes")
+  (println "migrations.012-add-sync-delete-work-indexes down")
   (h/sql "DROP INDEX sdw_cid_rid")
   (h/sql "DROP INDEX sdw_deleted"))


excludattu clojure.coren count jotta ei sen replacesta tule warningia

--- clj-elasticsearch/src/clj_elasticsearch/elastic_connect.clj
+++ clj-elasticsearch/src/clj_elasticsearch/elastic_connect.clj
@@ -1,4 +1,5 @@
 (ns clj-elasticsearch.elastic-connect
+    (:refer-clojure :exclude [count])
     (:require [clj-elasticsearch.elastic-utils :refer :all]
               [clj-http.client :as http]))