Skip to content

Commit

Permalink
Merge pull request #938 from AtlasOfLivingAustralia/feature/issue929
Browse files Browse the repository at this point in the history
site coverage
  • Loading branch information
chrisala authored Jun 5, 2024
2 parents 9af965b + e96522c commit 1a610cc
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 36 deletions.
34 changes: 13 additions & 21 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ if(!spatial.geoJsonEnvelopeConversionThreshold){
spatial.geoJsonEnvelopeConversionThreshold = 1_000_000
}

spatial.intersectionThreshold = 0.05

homepageIdx {
elasticsearch {
fieldsAndBoosts {
Expand Down Expand Up @@ -495,6 +497,13 @@ app {
}
}

site.check.boundary.layers = [
'cl927',
'cl10946',
'cl10921',
'cl2112'
]

/******************************************************************************\
* EXTERNAL SERVERS
\******************************************************************************/
Expand Down Expand Up @@ -551,29 +560,12 @@ if (!grails.cache.ehcache) {
enabled = true
ehcache {
cacheManagerName = appName + '-ehcache'
reloadable = true
diskStore = '/data/${appName}/ehcache'
diskStore = "/data/${appName}/ehcache"
ehcacheXmlLocation = 'classpath:ecodata-ehcache.xml'
}
}
}
}
grails.cache.config = {

provider {
name "${appName}-ehcache"
}
diskStore {
path "/data/${appName}/ehcache"
}
cache {
name 'userDetailsCache'
timeToLiveSeconds 60 * 60 * 24
maxElementsInMemory 2000
maxElementsOnDisk 2000
overflowToDisk true
diskPersistent true
}
}


security {
Expand Down Expand Up @@ -636,7 +628,7 @@ environments {
}
test {
// Override disk store so the travis build doesn't fail.
grails.cache.config = {
grails.cache.ehcache = {
diskStore {
path '/tmp'
}
Expand Down Expand Up @@ -665,7 +657,7 @@ environments {
security.cas.loginUrl="${security.cas.casServerUrlPrefix}/login"
}
meritfunctionaltest {
grails.cache.config = {
grails.cache.ehcache = {
diskStore {
path '/tmp'
}
Expand Down
3 changes: 3 additions & 0 deletions grails-app/conf/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ server:
servlet:
session:
timeout: 30m
shutdown: "graceful"
management:
endpoints:
enabled-by-default: false
Expand Down Expand Up @@ -202,6 +203,8 @@ quartz:

environments:
development:
server:
shutdown: "graceful"
grails.config.locations:
- ~/data/ecodata/config/ecodata-config.properties
test:
Expand Down
61 changes: 61 additions & 0 deletions grails-app/conf/ecodata-ehcache.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>

<persistence directory="/data/ecodata/ehcache"/>

<cache alias="spatialGeoJsonPid" uses-template="defaultSetting">
<expiry>
<none/>
</expiry>
<resources>
<disk unit="GB" persistent="true">10</disk>
</resources>
</cache>
<cache alias="spatialSearchObject" uses-template="defaultSetting">
<expiry>
<none/>
</expiry>

<resources>
<disk unit="MB" persistent="true">500</disk>
</resources>
</cache>

<cache alias="spatialSearchObjectMap" uses-template="defaultSetting">
<expiry>
<tti unit="minutes">2</tti>
</expiry>
<resources>
<heap unit="entries">200</heap>
</resources>
</cache>
<cache alias="spatialGeoJsonPidObject" uses-template="defaultSetting">
<expiry>
<tti unit="seconds">45</tti>
</expiry>
<resources>
<heap unit="entries">100</heap>
</resources>
</cache>
<cache alias="grailsTemplatesCache">
<key-type>java.io.Serializable</key-type>
<value-type>java.io.Serializable</value-type>
<expiry>
<ttl unit="hours">24</ttl>
</expiry>
<heap>10</heap>
</cache>
<cache alias="grailsBlocksCache">
<key-type>java.io.Serializable</key-type>
<value-type>java.io.Serializable</value-type>
<expiry>
<ttl unit="hours">24</ttl>
</expiry>
<heap>10</heap>
</cache>
<cache-template name="defaultSetting">
<key-type>java.io.Serializable</key-type>
<value-type>java.util.HashMap</value-type>
</cache-template>
</config>
8 changes: 4 additions & 4 deletions grails-app/conf/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
</encoder>
</appender>

<logger name="au.org.ala.ecodata" level="INFO">
<appender-ref ref="STDOUT" />
</logger>
<logger name="au.org.ala.ecodata" level="DEBUG" />

<logger name="org.ehcache" level="DEBUG" />

<root level="error">
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
96 changes: 96 additions & 0 deletions grails-app/controllers/au/org/ala/ecodata/AdminController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.apache.http.HttpStatus
import org.elasticsearch.action.search.SearchResponse
import org.elasticsearch.search.SearchHit
import org.grails.datastore.mapping.query.api.BuildableCriteria
import org.grails.plugin.cache.GrailsCacheManager
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormatter
import org.joda.time.format.ISODateTimeFormat
Expand Down Expand Up @@ -38,6 +39,7 @@ class AdminController {
RecordService recordService
ProjectActivityService projectActivityService
ParatooService paratooService
GrailsCacheManager grailsCacheManager

@AlaSecured(["ROLE_ADMIN"])
def index() {}
Expand Down Expand Up @@ -250,6 +252,89 @@ class AdminController {

offset += batchSize
}

def result = [code:code]
render result as JSON
}

@AlaSecured(["ROLE_ADMIN"])
def updateSiteLocationMetadata() {
def code = 'success'
def total = 0
def offset = 0
def batchSize = 100
def isMERIT = params.getBoolean('isMERIT', true)
def startTime = System.currentTimeMillis(), finishTime, startInterimTime, endInterimTime, batchStartTime, batchEndTime
List<String> fids = grailsApplication.config.getProperty('site.check.boundary.layers', List<String>)
def totalSites
List projectIds = []
if (isMERIT) {
projectIds = projectService.getAllMERITProjectIds()
totalSites = Site.countByStatusAndProjectsInList('active', projectIds)
}
else {
totalSites = Site.countByStatus('active')
}

def count = batchSize // For first loop iteration
while (count == batchSize) {
batchStartTime = startInterimTime = System.currentTimeMillis()
def sites
if (isMERIT) {
sites = Site.findAllByProjectsInListAndStatus(projectIds, 'active', [offset: offset, max: batchSize, sort: "siteId", order: "asc"]).collect {
siteService.toMap(it, 'flat')
}
}
else {
sites = Site.findAllByStatus('active', [offset: offset, max: batchSize, sort: "siteId", order: "asc"]).collect {
siteService.toMap(it, 'flat')
}
}
count = sites.size()
endInterimTime = System.currentTimeMillis()
log.debug("Time taken to fetch ${batchSize} records: ${endInterimTime - startInterimTime} ms")
startInterimTime = endInterimTime
Site.withSession { session -> session.clear() }
Site.withNewSession {
sites.eachWithIndex { site, index ->
try {
total++
if(total > 0 && (total % batchSize) == 0) {
log.info("${total+1} or ${(total+1)*100/totalSites} % sites updated in db..")
}

if (!site.projects || !site.extent) {
log.debug("Ignoring site ${site.siteId} due to no associated projects or no extent")
return
}
siteService.populateLocationMetadataForSite(site, fids)
endInterimTime = System.currentTimeMillis()
log.debug("Time taken to update metadata ${site.siteId}: ${endInterimTime - startInterimTime} ms")
startInterimTime = endInterimTime

if (site?.extent) {
siteService.update([extent: site.extent], site.siteId, false)
endInterimTime = System.currentTimeMillis()
log.debug("Time taken to update site ${site.siteId}: ${endInterimTime - startInterimTime} ms")
startInterimTime = endInterimTime
}
}
catch (Exception e) {
log.error("Unable to complete the operation ", e)
code = "error"
}
}
}

offset += batchSize

batchEndTime = System.currentTimeMillis()
log.debug("Time taken to process ${batchSize} records: ${batchEndTime - batchStartTime} ms")
}

finishTime = System.currentTimeMillis()
log.debug("site update compled in ${finishTime - startTime} ms")

def result = [code:code]
render result as JSON
}
Expand Down Expand Up @@ -782,4 +867,15 @@ class AdminController {
render text: template as JSON, status: HttpStatus.SC_OK, contentType: 'application/json'
}

@AlaSecured(["ROLE_ADMIN"])
def clearCache() {
def caches = grailsCacheManager.getCacheNames()
if (caches.contains(params.cache)) {
grailsCacheManager.getCache(params.cache).clear()
render text: [message: "Success"] as JSON, status: HttpStatus.SC_OK
}
else {
render text: [message: "Cache name not found"] as JSON, status: HttpStatus.SC_NOT_FOUND
}
}
}
1 change: 1 addition & 0 deletions grails-app/domain/au/org/ala/ecodata/Site.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Site {
name index: true
siteId index: true
projects index: true
status index: true
version false
}

Expand Down
5 changes: 5 additions & 0 deletions grails-app/init/au/org/ala/ecodata/BootStrap.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.bson.Transformer
import org.bson.types.ObjectId
import grails.core.ApplicationAttributes
import org.grails.datastore.mapping.mongo.MongoDatastore
import org.grails.plugin.cache.GrailsCacheManager
import org.grails.web.json.JSONObject
import org.grails.datastore.mapping.core.Datastore
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -31,6 +32,7 @@ class BootStrap {
def auditService
def hubService
def messageSource
def grailsCacheManager
@Autowired
MongoDatastore mongoDatastore

Expand Down Expand Up @@ -129,7 +131,10 @@ class BootStrap {
}

def destroy = {
// Close ehcache so that disk cached items are persisted. Otherwise, it will clear it the next time it starts up.
grailsCacheManager.destroy()
// shutdown ES server
elasticSearchService.destroy()
log.info "Shutting down - completed destroy method"
}
}
9 changes: 9 additions & 0 deletions grails-app/services/au/org/ala/ecodata/ProjectService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,15 @@ class ProjectService {
}
}

List<String> getAllMERITProjectIds() {
Project.withCriteria {
eq("isMERIT", true)
projections {
property("projectId")
}
}
}

/**
* Performs a case-insensitive search by project name
* @param name The project name to search for
Expand Down
6 changes: 3 additions & 3 deletions grails-app/services/au/org/ala/ecodata/SiteService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ class SiteService {
webService.getJson(url)
}

def populateLocationMetadataForSite(Map site) {
def populateLocationMetadataForSite(Map site, List<String> fids = null) {

Map siteGeom
if (site.type == Site.TYPE_COMPOUND) {
Expand Down Expand Up @@ -655,7 +655,7 @@ class SiteService {
log.error("No geometry for site: ${site.siteId}")
}

site.extent.geometry += lookupGeographicFacetsForSite(site)
site.extent.geometry += lookupGeographicFacetsForSite(site, fids)
}
}

Expand Down Expand Up @@ -852,7 +852,7 @@ class SiteService {
}
}
Map<String, List<String>> lookupGeographicFacetsForSite(Map site, List<String> fidsToLookup = null) {

log.debug("Looking up geographic facets for site: "+site.siteId)
Map<String, List<String>> geographicFacets = null
switch (site.extent.source) {
case 'pid':
Expand Down
Loading

0 comments on commit 1a610cc

Please sign in to comment.