Skip to content

Commit

Permalink
Merge pull request #357 from clowder-framework/release/1.20.2
Browse files Browse the repository at this point in the history
Release/1.20.2
  • Loading branch information
robkooper authored May 4, 2022
2 parents 86ba0e3 + 359df51 commit 68baf98
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 55 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ jobs:
- uses: actions/checkout@v2

- name: openapi-lint
uses: mhiew/redoc-lint-github-action@v2
uses: mbowman100/swagger-validator-action@master
with:
args: 'public/swagger.yml --skip-rule operation-operationId'
files: public/swagger.yml
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 1.20.2 - 2022-04-30

### Fixed
- swagger lint action
- When downloading a file with a `'` in the name it would save the file as blob
- Fix for a rare race condition with masonry where tiles could end up overlapping in space page.
- Fixes bug where same extractor shows up multiple times and all Clowder instances index db on reindex [#327](https://github.com/clowder-framework/clowder/issues/327)

### Changed
- Changed `Enabled By SuperAdmin` to read `Enabled by Server Admin` [#344](https://github.com/clowder-framework/clowder/issues/344)

## 1.20.1 - 2022-04-04

### Fixed
Expand Down
3 changes: 2 additions & 1 deletion app/services/mongodb/MongoDBQueueService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ trait MongoDBQueueService {

// start pool to being processing queue actions
def listen() = {
if (queueTimer == null) {
//only if this is the primary clowder instance
if (queueTimer == null && configuration.getBoolean("clowder.primary").getOrElse(true)) {
// TODO: Need to make these in a separate pool
queueTimer = Akka.system().scheduler.schedule(0 seconds, 5 millis) {
getNextQueuedAction match {
Expand Down
39 changes: 21 additions & 18 deletions app/services/rabbitmq/RabbitMQMessageService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,27 @@ class RabbitMQMessageService extends MessageService {
new MsgConsumer(channel.get, event_filter.get)
)

// Start actor to listen to extractor heartbeats
Logger.info("Starting extractor heartbeat listener")
// create fanout exchange if it doesn't already exist
channel.get.exchangeDeclare("extractors", "fanout", true)
// anonymous queue
val heartbeatsQueue = channel.get.queueDeclare().getQueue
// bind queue to exchange
channel.get.queueBind(heartbeatsQueue, "extractors", "*")
extractorsHeartbeats = Some(Akka.system.actorOf(
Props(new ExtractorsHeartbeats(channel.get, heartbeatsQueue)), name = "ExtractorsHeartbeats"
))
Logger.debug("Initializing a MsgConsumer for the ExtractorsHeartbeats")
channel.get.basicConsume(
heartbeatsQueue,
false, // do not auto ack
"ExtractorsHeartbeats", // tagging the consumer is important if you want to stop it later
new MsgConsumer(channel.get, extractorsHeartbeats.get)
)
//register new extractor only if this is the primary clowder instance
if (configuration.getBoolean("clowder.primary").getOrElse(true)) {
// Start actor to listen to extractor heartbeats
Logger.info("Starting extractor heartbeat listener")
// create fanout exchange if it doesn't already exist
channel.get.exchangeDeclare("extractors", "fanout", true)
// anonymous queue
val heartbeatsQueue = channel.get.queueDeclare().getQueue
// bind queue to exchange
channel.get.queueBind(heartbeatsQueue, "extractors", "*")
extractorsHeartbeats = Some(Akka.system.actorOf(
Props(new ExtractorsHeartbeats(channel.get, heartbeatsQueue)), name = "ExtractorsHeartbeats"
))
Logger.debug("Initializing a MsgConsumer for the ExtractorsHeartbeats")
channel.get.basicConsume(
heartbeatsQueue,
false, // do not auto ack
"ExtractorsHeartbeats", // tagging the consumer is important if you want to stop it later
new MsgConsumer(channel.get, extractorsHeartbeats.get)
)
}

// Setup Actor to submit new extractions to broker
extractQueue = Some(Akka.system.actorOf(Props(new PublishDirectActor(channel = channel.get,
Expand Down
39 changes: 11 additions & 28 deletions app/util/FileUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -856,37 +856,20 @@ object FileUtils {
//Download CONTENT-DISPOSITION encoding
//
def encodeAttachment(filename: String, userAgent: String) : String = {
val filenameStar = if (userAgent.indexOf("MSIE") > -1) {
URLEncoder.encode(filename, "UTF-8")
} else if (userAgent.indexOf("Edge") > -1){
MimeUtility.encodeText(filename
.replaceAll(",","%2C")
.replaceAll("\"","%22")
.replaceAll("/","%2F")
.replaceAll("=","%3D")
.replaceAll("&","%26")
.replaceAll(":","%3A")
.replaceAll(";","%3B")
.replaceAll("\\?","%3F")
.replaceAll("\\*","%2A")
val filenameStar = MimeUtility.encodeText(filename
.replaceAll("%","%25")
.replaceAll(" ","%20")
.replaceAll("\"","%22")
.replaceAll("'","%27")
.replaceAll(",","%2C")
.replaceAll("/","%2F")
.replaceAll("=","%3D")
.replaceAll(":","%3A")
.replaceAll(";","%3B")
.replaceAll("\\*","%2A")
,"utf-8","Q")
} else {
MimeUtility.encodeText(filename
.replaceAll("%","%25")
.replaceAll(" ","%20")
.replaceAll("\"","%22")
.replaceAll(",","%2C")
.replaceAll("/","%2F")
.replaceAll("=","%3D")
.replaceAll(":","%3A")
.replaceAll(";","%3B")
.replaceAll("\\*","%2A")
,"utf-8","Q")
}
Logger.debug(userAgent + ": " + filenameStar)

//Return the complete attachment header info
"attachment; filename*=UTF-8''" + filenameStar
}

}
2 changes: 1 addition & 1 deletion app/views/spaces/space.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ <h3>@Messages("collections.title")</h3>
match.masonry();

// layout Masonry again after all images have loaded
imagesLoaded( '.tiled-image', function() {
imagesLoaded( match, function() {
match.masonry({
itemSelector: '.tiled-image',
columnWidth: '.post-box',
Expand Down
4 changes: 2 additions & 2 deletions app/views/spaces/updateExtractors.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ <h1>Space Extractors</h1>
<th>Name</th>
<th>Description</th>
<th>Process Triggers</th>
<th class="text-center" title="Extractors marked for execution in all spaces">Enabled By SuperAdmin</th>
<th class="text-center" title="Follow selection in 'Enabled By SuperAdmin' column">Use Default</th>
<th class="text-center" title="Extractors marked for execution in all spaces">Enabled by Server Admin</th>
<th class="text-center" title="Follow selection in 'Enabled by Server Admin' column">Use Default</th>
<th class="text-center" title="Always trigger execution in this space">Enable in Space</th>
<th class="text-center" title="Never trigger execution in this space">Disable in Space</th>
</tr>
Expand Down
7 changes: 7 additions & 0 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ api.version="beta"
# mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
mongodbURI = "mongodb://127.0.0.1:27017/clowder"

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Clowder Primary Instance
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This is required if there are multiple clowder instances. This config variable indicates
# the primary clowder instance who takes care of special actions like registering new extractors,
# indexing db on a reindex etc. The default value is true which means only one instance of clowder running.
clowder.primary=true

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# RabbitMQ
Expand Down
2 changes: 1 addition & 1 deletion doc/src/sphinx/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'Luigi Marini'

# The full version, including alpha/beta/rc tags
release = '1.20.1'
release = '1.20.2'


# -- General configuration ---------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions docker/custom.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ smtp.host=${?SMTP_SERVER}
service.byteStorage=services.filesystem.DiskByteStorageService
service.byteStorage=${?CLOWDER_STORAGE}

#primary Clowder instance
clowder.primary=true
clowder.primary=${?CLOWDER_PRIMARY}

# location in case of services.filesystem.DiskByteStorageService
clowder.diskStorage.path="/home/clowder/data"
clowder.diskStorage.path=${?CLOWDER_DISKPATH}
Expand Down
2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import NativePackagerKeys._
object ApplicationBuild extends Build {

val appName = "clowder"
val version = "1.20.1"
val version = "1.20.2"
val jvm = "1.7"

def appVersion: String = {
Expand Down
2 changes: 1 addition & 1 deletion public/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ info:
Clowder is a customizable and scalable data management system to support any
data format and multiple research domains. It is under active development
and deployed for a variety of research projects.
version: 1.20.1
version: 1.20.2
termsOfService: https://clowder.ncsa.illinois.edu/clowder/tos
contact:
name: Clowder
Expand Down

0 comments on commit 68baf98

Please sign in to comment.