Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preparing v5.1 #1046

Merged
merged 69 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
d185b29
Progress commit for #994
chrisala Aug 5, 2024
df5ab74
Search associated orgs for project organisationId search #994
chrisala Aug 21, 2024
f51472f
Updated tests #994
chrisala Aug 21, 2024
7852d33
Added business/contract names #994
chrisala Aug 26, 2024
d56fb9b
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Aug 26, 2024
71707f6
Changed OrganisationService to use data binding #994
chrisala Aug 27, 2024
d2e7dbd
Remove dynamic property check from test #994
chrisala Aug 27, 2024
b6aba4e
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 6, 2024
8e638ca
Update org names when contract names changed #994
chrisala Sep 9, 2024
232113b
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 16, 2024
9458a7c
Disable org collectory sync by default #2382
chrisala Sep 16, 2024
a83a3f7
Ensure BioCollect associated orgs use org name to preserve behaviour …
chrisala Sep 17, 2024
e62a356
Updated tests #994
chrisala Sep 17, 2024
3fc5fa9
Updated tests #994
chrisala Sep 17, 2024
9f470e4
Updated tests #994
chrisala Sep 17, 2024
075a938
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 17, 2024
72878cd
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 19, 2024
a7f2da6
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 19, 2024
3a11b8e
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 25, 2024
3960819
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Sep 25, 2024
6d9552a
5.1-SNAPSHOT
temi Oct 3, 2024
bde9655
Merge remote-tracking branch 'origin/dev' into feature/issue994
chrisala Oct 3, 2024
10310f9
Use "Recipient" for default org relationship #994
chrisala Oct 3, 2024
5af34df
Moved script to merit #994
chrisala Oct 4, 2024
ae87e04
Bump cookie and socket.io
dependabot[bot] Oct 10, 2024
480a254
Use associatedOrgs for project organisation data on export #994
chrisala Oct 15, 2024
a6c3ee7
Addressing code review comments #994
chrisala Oct 16, 2024
fe57bd0
Merge pull request #1031 from AtlasOfLivingAustralia/feature/issue994
temi Oct 16, 2024
c300e2d
Moved org script to release #994
chrisala Oct 18, 2024
b20081d
AtlasOfLivingAustralia/fieldcapture#2789
temi Oct 24, 2024
4e82da7
Merge pull request #1033 from AtlasOfLivingAustralia/feature/issue2789
chrisala Oct 28, 2024
8270543
AtlasOfLivingAustralia/fieldcapture#1724
temi Oct 31, 2024
60acf18
Merge pull request #1035 from AtlasOfLivingAustralia/feature/issue1724
chrisala Oct 31, 2024
8cb4e8e
Merge pull request #1030 from AtlasOfLivingAustralia/dependabot/npm_a…
chrisala Oct 31, 2024
4f7fa4a
Add external id for tech one orgs #994
chrisala Nov 1, 2024
bf2d349
Merge pull request #1036 from AtlasOfLivingAustralia/feature/issue994
salomon-j Nov 1, 2024
be9439f
AtlasOfLivingAustralia/fieldcapture#1724 & #1034
temi Nov 1, 2024
8c314f0
AtlasOfLivingAustralia/fieldcapture#1724 & #1034
temi Nov 5, 2024
117b875
Merge pull request #1037 from AtlasOfLivingAustralia/feature/issue1724
chrisala Nov 5, 2024
4c32c0b
AtlasOfLivingAustralia/fieldcapture#1724 & #1034
temi Nov 5, 2024
2028d84
Merge pull request #1038 from AtlasOfLivingAustralia/feature/issue1724
chrisala Nov 5, 2024
780dd9f
Added org details / orgMintedIdentifier to downlaods #994 #1039
chrisala Nov 6, 2024
542071e
Added project dates / renamed org column in downloads #994
chrisala Nov 17, 2024
4106997
Blank MERIT org name from unlinked orgs in download #994
chrisala Nov 17, 2024
68b7743
Merge pull request #1041 from AtlasOfLivingAustralia/feature/issue994
salomon-j Nov 20, 2024
ec5dcbe
AtlasOfLivingAustralia/fieldcapture#3369
temi Nov 22, 2024
a175800
AtlasOfLivingAustralia/biocollect#1546
temi Jun 16, 2023
2925ace
Implemented project activities indexing for the home page / project s…
jack-brinkman Jul 31, 2023
144ddd0
Updated homepage project activities indexing to use projectActivitySe…
jack-brinkman Aug 3, 2023
1e3e3e6
migrated code necessary for PWA from feature/cognito branch
temi Nov 27, 2024
8d2f0dd
5.1-PWA-SNAPSHOT
temi Nov 27, 2024
5e61def
change from code review
temi Nov 28, 2024
2c72713
Merge branch 'dev' into feature/pwa2
temi Nov 28, 2024
23ca722
Merge pull request #1043 from AtlasOfLivingAustralia/feature/pwa2
temi Nov 28, 2024
e957a95
Update build.gradle
chrisala Dec 2, 2024
b50ebab
fix for issue with not finding monitor user
temi Dec 3, 2024
ad8d821
Merge pull request #1044 from AtlasOfLivingAustralia/feature/pwa2
chrisala Dec 3, 2024
de75e7e
Stub spatial due to errors AtlasOfLivingAustralia/fieldcapture#3368
chrisala Dec 3, 2024
b0bc704
Added name identifier for the Score entity AtlasOfLivingAustralia/fie…
chrisala Dec 8, 2024
49abd9c
Back to 5.1-SNAPSHOT AtlasOfLivingAustralia/fieldcapture#3368
chrisala Dec 8, 2024
5fa4080
adding published survey flag to projectActivities
temi Dec 10, 2024
e112405
Fixed poi-ooxml dependencies AtlasOfLivingAustralia/fieldcapture#3384
chrisala Dec 10, 2024
9515f60
Merge branch 'dev' into feature/issue3369
temi Dec 11, 2024
3387de2
project activity change trigger update of project
temi Dec 11, 2024
b3203b2
Merge pull request #1045 from AtlasOfLivingAustralia/feature/pwa2
jack-brinkman Dec 11, 2024
b756005
Stub spatial due to errors AtlasOfLivingAustralia/fieldcapture#3368
chrisala Dec 3, 2024
1fdd361
project activity change trigger update of project
temi Dec 11, 2024
9d54231
ala security plugin 6.3.0
temi Dec 12, 2024
644de69
Merge pull request #1042 from AtlasOfLivingAustralia/feature/issue3369
chrisala Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ plugins {
id "com.gorylenko.gradle-git-properties" version "2.4.1"
}

version "5.0.1"
version "5.1-SNAPSHOT"
group "au.org.ala"
description "Ecodata"

Expand Down Expand Up @@ -105,6 +105,7 @@ dependencies {

implementation 'org.apache.poi:poi:5.2.2'
implementation 'org.apache.poi:poi-ooxml:5.2.2'
implementation 'org.apache.poi:poi-ooxml-full:5.2.2'
implementation 'org.codehaus.groovy:groovy-dateutil:3.0.8'

implementation "org.grails.plugins:ala-auth:$alaSecurityLibsVersion"
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ gormMongoVersion=8.2.0
grailsViewsVersion=2.3.2
assetPipelineVersion=4.3.0
elasticsearchVersion=7.17.21
alaSecurityLibsVersion=6.3.0-SNAPSHOT
alaSecurityLibsVersion=6.3.0
#22.x+ causes issues with mongo / GORM javax.validation.spi, might need grails 5
geoToolsVersion=21.5
#jtsVersion must match the geotools version
Expand Down
22 changes: 20 additions & 2 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,24 @@ app {
}
checkForBoundaryIntersectionInLayers = [ "cl927", "cl11163" ]
}
displayNames = [elect: "Electorate(s)", state: "State(s)"]
displayNames = [
elect: [
headerName: "Electorate(s)"
],
state: [
headerName: "State(s)",
mappings: [
"Northern Territory": ["Northern Territory (including Coastal Waters)", "NT"],
"Tasmania": ["Tasmania (including Coastal Waters)", "TAS"],
"New South Wales": ["New South Wales (including Coastal Waters)", "NSW"],
"Victoria": ["Victoria (including Coastal Waters)", "VIC"],
"Queensland": ["Queensland (including Coastal Waters)", "QLD"],
"South Australia": ["South Australia (including Coastal Waters)", "SA"],
"Australian Capital Territory": ["ACT"],
"Western Australia": ["Western Australia (including Coastal Waters)", "WA"]
]
]
]
}
}
/******************************************************************************\
Expand Down Expand Up @@ -654,7 +671,7 @@ environments {
ecodata.use.uuids = false
app.external.model.dir = "./models/"
grails.serverURL = "http://localhost:8080"
app.uploads.url = "${grails.serverURL}/document/download?filename="
app.uploads.url = "/document/download/"

app.elasticsearch.indexOnGormEvents = true
app.elasticsearch.indexAllOnStartup = true
Expand Down Expand Up @@ -683,6 +700,7 @@ environments {
audit.thread.schedule.interval = 500l;

paratoo.core.baseUrl = "http://localhost:${wiremock.port}/monitor"
spatial.baseUrl = "http://localhost:${wiremock.port}"
}
production {
grails.logging.jul.usebridge = false
Expand Down
11 changes: 7 additions & 4 deletions grails-app/conf/data/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@
"organisationId": {
"type" : "keyword"
},
"orgIdSvcProvider": {
"type" : "keyword",
"copy_to": ["organisationId"]
},
"organisationName": {
"type" : "text",
"copy_to": ["organisationFacet", "organisationSort"]
Expand All @@ -96,6 +92,13 @@
"type" : "text",
"copy_to": ["organisationName","organisationFacet", "organisationSort"]
},
"lastUpdated": {
"type" : "date",
"copy_to" : "lastUpdatedSort"
},
"lastUpdatedSort" : {
"type" : "keyword", "normalizer" : "case_insensitive_sort"
},
"associatedOrgs": {
"properties" : {
"name" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ApiKeyInterceptor {
PreAuthorise pa = method.getAnnotation(PreAuthorise) ?: controllerClass.getAnnotation(PreAuthorise)

if (pa.basicAuth()) {
au.org.ala.web.UserDetails user = userService.getUserFromJWT()
def user = userService.setUser()
request.userId = user?.userId
if(permissionService.isUserAlaAdmin(request.userId)) {
/* Don't enforce check for ALA admin.*/
Expand Down
18 changes: 2 additions & 16 deletions grails-app/controllers/au/org/ala/ecodata/AuditInterceptor.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import grails.config.Config
class AuditInterceptor implements GrailsConfigurationAware {

int order = 100 // This needs to be after the @RequireApiKey interceptor which makes the userId available via the authService
String httpRequestHeaderForUserId
static String httpRequestHeaderForUserId
UserService userService
AuthService authService

Expand All @@ -16,21 +16,7 @@ class AuditInterceptor implements GrailsConfigurationAware {
}

boolean before() {
// userId is set from either the request param userId or failing that it tries to get it from
// the UserPrincipal (assumes ecodata is being accessed directly via admin page)
def userId = authService.getUserId() ?: request.getHeader(httpRequestHeaderForUserId)
if (userId) {
def userDetails = userService.setCurrentUser(userId)
if (userDetails) {
// We set the current user details in the request scope because
// the 'afterView' hook can be called prior to the actual rendering (despite the name)
// and the thread local can get clobbered before it is actually required.
// Consumers who have access to the request can simply extract current user details
// from there rather than use the service.
request.setAttribute(UserDetails.REQUEST_USER_DETAILS_KEY, userDetails)
}
}

userService.setUser()
true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class ProjectActivityController {
}

if (!result) {
result = [status: 404, text: 'Invalid id'];
render status: 404, text: [message: 'Invalid id', status: 404] as JSON
return
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,15 @@ class ProjectController {
render result as JSON
}

def findStateAndElectorateForProject() {
if (!params.projectId) {
render status:400, text: "projectId is a required parameter"
} else {
Map project = projectService.get(params.projectId)
asJson projectService.findStateAndElectorateForProject(project)
}
}

def findByName() {
if (!params.projectName) {
render status:400, text: "projectName is a required parameter"
Expand Down
134 changes: 134 additions & 0 deletions grails-app/controllers/au/org/ala/ecodata/SpatialController.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package au.org.ala.ecodata

import au.org.ala.ecodata.spatial.SpatialConversionUtils
import au.org.ala.ecodata.spatial.SpatialUtils
import org.apache.commons.fileupload.servlet.ServletFileUpload
import org.apache.commons.io.IOUtils
import org.apache.commons.lang3.tuple.Pair
import org.locationtech.jts.geom.Geometry
import org.springframework.web.multipart.MultipartFile

import javax.servlet.http.HttpServletResponse
@au.ala.org.ws.security.RequireApiKey(scopesFromProperty=["app.readScope"])
class SpatialController {
SpatialService spatialService
static responseFormats = ['json', 'xml']
static allowedMethods = [uploadShapeFile: "POST", getShapeFileFeatureGeoJson: "GET"]

@au.ala.org.ws.security.RequireApiKey(scopesFromProperty=["app.writeScope"])
def uploadShapeFile() {
// Use linked hash map to maintain key ordering
Map<Object, Object> retMap = new LinkedHashMap<Object, Object>()

File tmpZipFile = File.createTempFile("shpUpload", ".zip")

if (ServletFileUpload.isMultipartContent(request)) {
// Parse the request
Map<String, MultipartFile> items = request.getFileMap()

if (items.size() == 1) {
MultipartFile fileItem = items.values()[0]
IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(tmpZipFile))
retMap.putAll(handleZippedShapeFile(tmpZipFile))
response.setStatus(HttpServletResponse.SC_OK)
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST)
retMap.put("error", "Multiple files sent in request. A single zipped shape file should be supplied.")
}
}

respond retMap
}

@au.ala.org.ws.security.RequireApiKey(scopesFromProperty=["app.writeScope"])
def getShapeFileFeatureGeoJson() {
Map retMap
String shapeId = params.shapeFileId
String featureIndex = params.featureId
if (featureIndex != null && shapeId != null) {

retMap = processShapeFileFeatureRequest(shapeId, featureIndex)
if(retMap.geoJson == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST)
}
else {
response.setStatus(HttpServletResponse.SC_OK)
}
}
else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST)
retMap = ["error": "featureId and shapeFileId must be supplied"]
}

respond retMap
}

def features() {
def retVariable
if (!params.layerId) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST)
retVariable = ["error": "layerId must be supplied"]
}
else {
List<String> intersectWith = params.intersectWith?.split(",") ?: []
retVariable = spatialService.features(params.layerId, intersectWith)
}

respond retVariable
}

private Map<String, String> processShapeFileFeatureRequest(String shapeFileId, String featureIndex) {
Map<String, Object> retMap = new HashMap<String, Object>()

try {
File shpFileDir = new File(System.getProperty("java.io.tmpdir"), shapeFileId)
Geometry geoJson = SpatialUtils.getShapeFileFeaturesAsGeometry(shpFileDir, featureIndex)

if (geoJson == null) {
retMap.put("error", "Invalid geometry")
return retMap
}
else {
if (geoJson.getCoordinates().flatten().size() > grailsApplication.config.getProperty("shapefile.simplify.threshhold", Integer, 50_000)) {
geoJson = GeometryUtils.simplify(geoJson, grailsApplication.config.getProperty("shapefile.simplify.tolerance", Double, 0.0001))
}

retMap.put("geoJson", GeometryUtils.geometryToGeoJsonMap(geoJson, grailsApplication.config.getProperty("shapefile.geojson.decimal", Integer, 20)))
}
} catch (Exception ex) {
log.error("Error processsing shapefile feature request", ex)
retMap.put("error", ex.getMessage())
}

return retMap
}

private static Map<Object, Object> handleZippedShapeFile(File zippedShp) throws IOException {
// Use linked hash map to maintain key ordering
Map<Object, Object> retMap = new LinkedHashMap<Object, Object>()

Pair<String, File> idFilePair = SpatialConversionUtils.extractZippedShapeFile(zippedShp)
String uploadedShpId = idFilePair.getLeft()
File shpFile = idFilePair.getRight()

retMap.put("shp_id", uploadedShpId)

List<List<Pair<String, Object>>> manifestData = SpatialConversionUtils.getShapeFileManifest(shpFile)

int featureIndex = 0
for (List<Pair<String, Object>> featureData : manifestData) {
// Use linked hash map to maintain key ordering
Map<String, Object> featureDataMap = new LinkedHashMap<String, Object>()

for (Pair<String, Object> fieldData : featureData) {
featureDataMap.put(fieldData.getLeft(), fieldData.getRight())
}

retMap.put(featureIndex, featureDataMap)

featureIndex++
}

return retMap
}
}
4 changes: 4 additions & 0 deletions grails-app/controllers/au/org/ala/ecodata/UrlMappings.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class UrlMappings {

"/ws/output/getOutputSpeciesUUID/"(controller: "output"){ action = [GET:"getOutputSpeciesUUID"] }

"/ws/shapefile" (controller: "spatial"){ action = [POST:"uploadShapeFile"] }
"/ws/shapefile/geojson/$shapeFileId/$featureId"(controller: "spatial"){ action = [GET:"getShapeFileFeatureGeoJson"] }

"/ws/activitiesForProject/$id" {
controller = 'activity'
action = 'activitiesForProject'
Expand Down Expand Up @@ -195,6 +198,7 @@ class UrlMappings {
"/ws/project/getBiocollectFacets"(controller: "project"){ action = [GET:"getBiocollectFacets"] }
"/ws/project/getDefaultFacets"(controller: "project", action: "getDefaultFacets")
"/ws/project/$projectId/dataSet/$dataSetId/records"(controller: "project", action: "fetchDataSetRecords")
"/ws/project/findStateAndElectorateForProject"(controller: "project", action: "findStateAndElectorateForProject")
"/ws/admin/initiateSpeciesRematch"(controller: "admin", action: "initiateSpeciesRematch")
"/ws/dataSetSummary/$projectId/$dataSetId?"(controller :'dataSetSummary') {

Expand Down
21 changes: 21 additions & 0 deletions grails-app/domain/au/org/ala/ecodata/AssociatedOrg.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,29 @@ import groovy.transform.ToString
@JsonIgnoreProperties(['metaClass', 'errors', 'expandoMetaClass'])
class AssociatedOrg {

/** Reference to the Organisation entity if ecodata has a record of the Organisation */
String organisationId

/**
* The name of the organisation in the context of the relationship. e.g. it could be a name used
* in a contract with a project that is different from the current business name of the organisation
*/
String name
String logo
String url

/**
* The date the association started. A null date indicates the relationship started at the same
* time as the related entity. e.g. the start of a Project
*/
Date fromDate

/**
* The date the association e ended. A null date indicates the relationship ended at the same
* time as the related entity. e.g. the end of a Project
*/
Date toDate

/** A description of the association - e.g. Service Provider, Grantee, Sponsor */
String description

Expand All @@ -25,8 +43,11 @@ class AssociatedOrg {
organisationId nullable: true
name nullable: true
logo nullable: true

url nullable: true
description nullable: true
fromDate nullable: true
toDate nullable: true
}

}
2 changes: 1 addition & 1 deletion grails-app/domain/au/org/ala/ecodata/ExternalId.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ExternalId implements Comparable {

enum IdType {
INTERNAL_ORDER_NUMBER, TECH_ONE_CODE, WORK_ORDER, GRANT_AWARD, GRANT_OPPORTUNITY, RELATED_PROJECT,
MONITOR_PROTOCOL_INTERNAL_ID, MONITOR_PROTOCOL_GUID, TECH_ONE_CONTRACT_NUMBER, MONITOR_PLOT_GUID,
MONITOR_PROTOCOL_INTERNAL_ID, MONITOR_PROTOCOL_GUID, TECH_ONE_CONTRACT_NUMBER, TECH_ONE_PARTY_ID, MONITOR_PLOT_GUID,
MONITOR_PLOT_SELECTION_GUID, MONITOR_MINTED_COLLECTION_ID, UNSPECIFIED }

static constraints = {
Expand Down
6 changes: 6 additions & 0 deletions grails-app/domain/au/org/ala/ecodata/GeographicInfo.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ class GeographicInfo {
/** Some projects don't have specific geographic areas and are flagged as being run nationwide */
boolean nationwide = false

/** A flag to indicate that the project is running statewide i.e. all electorates in a state */
boolean statewide = false

/** A flag to override calculated values for states and electorates with manually entered values */
boolean isDefault = false

/** The primary state in which this project is running, if applicable */
String primaryState

Expand Down
Loading
Loading