Skip to content

Commit

Permalink
Merge pull request #309 from MauroDataMapper/feature/mc-9833
Browse files Browse the repository at this point in the history
Subscribed catalogue support for Atom XML and importing from published URLs
  • Loading branch information
olliefreeman authored Jun 13, 2022
2 parents d5a9180 + 0f59b2c commit ff5dc5a
Show file tree
Hide file tree
Showing 89 changed files with 2,301 additions and 963 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
UPDATE core.domain_export
SET export_content_type = export_file_type
WHERE export_content_type IS NULL;

ALTER TABLE core.domain_export
ALTER COLUMN export_content_type SET NOT NULL;

ALTER TABLE core.domain_export
DROP COLUMN export_file_type;
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class DomainExport implements MdmDomain {
MdmDomain exportedDomain
byte[] exportData
String exportFileName
String exportFileType
String exportContentType

String exporterNamespace
Expand All @@ -55,7 +54,6 @@ class DomainExport implements MdmDomain {
exporterNamespace blank: false
exporterName blank: false
exportFileName blank: false
exportFileType blank: false
exportContentType nullable: true, blank: false
}

Expand Down Expand Up @@ -94,8 +92,7 @@ class DomainExport implements MdmDomain {
this.exporterNamespace = exporterProviderService.namespace
this.exporterName = exporterProviderService.name
this.exporterVersion = exporterProviderService.sortableVersion()
this.exportFileType = exporterProviderService.fileType
this.exportContentType = exporterProviderService.producesContentType
this.exportContentType = exporterProviderService.contentType
}

Map getDownloadLinkParams() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import org.springframework.beans.factory.annotation.Autowired
@CompileStatic
class FolderJsonExporterService extends FolderExporterProviderService implements TemplateBasedExporter {

public static final CONTENT_TYPE = 'application/mauro.folder+json'

@Autowired
JsonViewTemplateEngine templateEngine

Expand All @@ -45,19 +47,14 @@ class FolderJsonExporterService extends FolderExporterProviderService implements
'1.0'
}

@Override
String getFileType() {
'text/json'
}

@Override
String getFileExtension() {
'json'
}

@Override
String getProducesContentType() {
'application/mdm+json'
String getContentType() {
CONTENT_TYPE
}

@Override
Expand All @@ -73,7 +70,7 @@ class FolderJsonExporterService extends FolderExporterProviderService implements
@Override
ByteArrayOutputStream exportFolder(User currentUser, Folder folder, Map<String, Object> parameters) throws ApiException {
ExportMetadata exportMetadata = new ExportMetadata(this, currentUser.firstName, currentUser.lastName)
exportModel(new ExportModel(folder, 'folder', version, exportMetadata), fileType)
exportModel(new ExportModel(folder, 'folder', version, exportMetadata), contentType)
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import uk.ac.ox.softeng.maurodatamapper.core.provider.importer.parameter.Importe
import uk.ac.ox.softeng.maurodatamapper.core.provider.importer.parameter.config.ImportParameterConfig
import uk.ac.ox.softeng.maurodatamapper.core.rest.transport.importer.ImportParameterGroup
import uk.ac.ox.softeng.maurodatamapper.security.User
import uk.ac.ox.softeng.maurodatamapper.traits.domain.MdmDomain

import grails.validation.ValidationErrors
import grails.web.databinding.DataBinder
Expand All @@ -57,12 +58,15 @@ class ImporterService implements DataBinder {
@Autowired
MessageSource messageSource

public <M extends Model, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> List<M> importDomains(
@Autowired(required = false)
Set<ImporterProviderService> importerProviderServices

public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> List<M> importDomains(
User currentUser, T importer, P importParams) {
importer.importDomains(currentUser, importParams).findAll()
}

public <M extends Model, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> M importDomain(
public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> M importDomain(
User currentUser, T importer, P importParams) {
M model = importer.importDomain(currentUser, importParams)

Expand Down Expand Up @@ -212,4 +216,35 @@ class ImporterService implements DataBinder {
importerProviderServiceParameters
}

public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> List<T> findImporterProviderServicesByContentType(
String contentType) {
importerProviderServices.findAll {it.handlesContentType(contentType)}.sort()
}

public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> T findImporterProviderServiceByContentType(
String contentType) {
findImporterProviderServicesByContentType(contentType).first()
}

public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> T findImporterProviderServiceByContentType(
String namespace, String name, String version, String contentType) {
findImporterProviderServices(namespace, name, version).findAll {it.handlesContentType(contentType)}.sort().first()
}

public <M extends MdmDomain, P extends ImporterProviderServiceParameters, T extends ImporterProviderService<M, P>> List<T> findImporterProviderServices(String namespace,
String name,
String version) {
if (version) {
importerProviderServices.findAll {
it.namespace.equalsIgnoreCase(namespace) &&
it.name.equalsIgnoreCase(name) &&
it.version.equalsIgnoreCase(version)
}.sort()
} else {
importerProviderServices.findAll {
it.namespace.equalsIgnoreCase(namespace) &&
it.name.equalsIgnoreCase(name)
}.sort()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2020-2022 University of Oxford and Health and Social Care Information Centre, also known as NHS Digital
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package uk.ac.ox.softeng.maurodatamapper.core.rest.transport.importer

import grails.validation.Validateable

class ImporterProviderServiceData implements Validateable {
String name
String namespace
String version

static constraints = {
version nullable: true, blank: false
}
}
1 change: 0 additions & 1 deletion mdm-core/grails-app/views/domainExport/_domainExport.gson
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ json {

export {
fileName domainExport.exportFileName
fileType domainExport.exportFileType
contentType domainExport.exportContentType
fileSize domainExport.exportFileSize
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ model {

json {
fileExtension exporterProviderService.fileExtension
fileType exporterProviderService.fileType
contentType exporterProviderService.contentType
canExportMultipleDomains exporterProviderService.canExportMultipleDomains()
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class DomainExportFunctionalSpec extends BaseFunctionalSpec {
}

@Override
String getFileType() {
String getContentType() {
grails.web.mime.MimeType.JSON.name
}

Expand Down Expand Up @@ -157,8 +157,7 @@ class DomainExportFunctionalSpec extends BaseFunctionalSpec {
},
"export": {
"fileName": "test.json",
"fileType": "application/json",
"contentType": null,
"contentType": "application/json",
"fileSize": 20
},
"exportedOn": "${json-unit.matches:offsetDateTime}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class MauroDataMapperServiceProviderFunctionalSpec extends BaseFunctionalSpec {
],
"providerType": "FolderExporter",
"fileExtension": "json",
"fileType": "text/json",
"contentType": "application/mauro.folder+json",
"canExportMultipleDomains": false
}
]''')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,11 @@ abstract class ExporterProviderService extends MauroDataMapperService {

abstract String getFileExtension()

abstract String getFileType()

/**
* MIME type produced by ExporterProviderService
* @return MIME type
*/
String getProducesContentType() {
null
}
abstract String getContentType()

@Override
String getProviderType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ import uk.ac.ox.softeng.maurodatamapper.core.provider.ProviderType
import uk.ac.ox.softeng.maurodatamapper.core.provider.importer.parameter.ImporterProviderServiceParameters
import uk.ac.ox.softeng.maurodatamapper.provider.MauroDataMapperService
import uk.ac.ox.softeng.maurodatamapper.security.User
import uk.ac.ox.softeng.maurodatamapper.traits.domain.MdmDomain

import groovy.transform.CompileStatic
import org.springframework.core.GenericTypeResolver

@CompileStatic
abstract class ImporterProviderService<D extends CatalogueItem, T extends ImporterProviderServiceParameters>
abstract class ImporterProviderService<D extends MdmDomain, T extends ImporterProviderServiceParameters>
extends MauroDataMapperService {

abstract D importDomain(User currentUser, T params)
Expand All @@ -37,6 +38,8 @@ abstract class ImporterProviderService<D extends CatalogueItem, T extends Import

abstract Boolean canImportMultipleDomains()

abstract Boolean handlesContentType(String contentType)

List<String> getImportBlacklistedProperties() {
['id', 'domainType', 'lastUpdated']
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,5 +230,10 @@ otherwise you could get an error.''',
String getVersion() {
'1.0'
}

@Override
Boolean handlesContentType(String contentType) {
contentType.equalsIgnoreCase('application/mauro.test')
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ otherwise you could get an error.''',
null
}

@Override
Boolean handlesContentType(String contentType) {
contentType.equalsIgnoreCase('application/mauro.test')
}

@Override
String getDisplayName() {
'Test Importer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class DataFlowController extends EditLoggingController<DataFlow> {
return errorResponse(UNPROCESSABLE_ENTITY, 'DataFlow could not be exported')
}

render(file: outputStream.toByteArray(), fileName: "${instance.label}.${exporter.fileExtension}", contentType: exporter.fileType)
render(file: outputStream.toByteArray(), fileName: "${instance.label}.${exporter.fileExtension}", contentType: exporter.contentType)
}

def exportDataFlows() {
Expand Down Expand Up @@ -128,7 +128,7 @@ class DataFlowController extends EditLoggingController<DataFlow> {
return errorResponse(UNPROCESSABLE_ENTITY, 'DataFlows could not be exported')
}

render(file: outputStream.toByteArray(), fileName: "DataFlows.${exporter.fileExtension}", contentType: exporter.fileType)
render(file: outputStream.toByteArray(), fileName: "DataFlows.${exporter.fileExtension}", contentType: exporter.contentType)
}

private DataFlowImporterProviderService findImporter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired
*/
class DataFlowJsonExporterService extends DataFlowExporterProviderService implements TemplateBasedExporter {

public static final CONTENT_TYPE = 'application/mauro.dataflow+json'

@Autowired
JsonViewTemplateEngine templateEngine

Expand All @@ -42,13 +44,8 @@ class DataFlowJsonExporterService extends DataFlowExporterProviderService implem
}

@Override
String getFileType() {
'text/json'
}

@Override
String getProducesContentType() {
'application/mdm+json'
String getContentType() {
CONTENT_TYPE
}

@Override
Expand All @@ -69,7 +66,7 @@ class DataFlowJsonExporterService extends DataFlowExporterProviderService implem
@Override
ByteArrayOutputStream exportDataFlow(User currentUser, DataFlow dataFlow, Map<String, Object> parameters) throws ApiException {
ExportMetadata exportMetadata = new ExportMetadata(this, currentUser.firstName, currentUser.lastName)
exportModel new ExportModel(dataFlow, 'dataFlow', version, exportMetadata), fileType
exportModel new ExportModel(dataFlow, 'dataFlow', version, exportMetadata), contentType
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired
*/
class DataFlowXmlExporterService extends DataFlowExporterProviderService implements TemplateBasedExporter {

public static final CONTENT_TYPE = 'application/mauro.dataflow+xml'

@Autowired
MarkupViewTemplateEngine templateEngine

Expand All @@ -42,13 +44,8 @@ class DataFlowXmlExporterService extends DataFlowExporterProviderService impleme
}

@Override
String getFileType() {
'text/xml'
}

@Override
String getProducesContentType() {
'application/mdm+xml'
String getContentType() {
CONTENT_TYPE
}

@Override
Expand All @@ -69,7 +66,7 @@ class DataFlowXmlExporterService extends DataFlowExporterProviderService impleme
@Override
ByteArrayOutputStream exportDataFlow(User currentUser, DataFlow dataFlow, Map<String, Object> parameters) throws ApiException {
ExportMetadata exportMetadata = new ExportMetadata(this, currentUser.firstName, currentUser.lastName)
exportModel new ExportModel(dataFlow, 'dataFlow', version, 'gml', exportMetadata), fileType
exportModel new ExportModel(dataFlow, 'dataFlow', version, 'gml', exportMetadata), contentType
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import uk.ac.ox.softeng.maurodatamapper.api.exception.ApiBadRequestException
import uk.ac.ox.softeng.maurodatamapper.api.exception.ApiUnauthorizedException
import uk.ac.ox.softeng.maurodatamapper.core.traits.provider.importer.JsonImportMapping
import uk.ac.ox.softeng.maurodatamapper.dataflow.DataFlow
import uk.ac.ox.softeng.maurodatamapper.dataflow.provider.exporter.DataFlowJsonExporterService
import uk.ac.ox.softeng.maurodatamapper.dataflow.provider.importer.parameter.DataFlowFileImporterProviderServiceParameters
import uk.ac.ox.softeng.maurodatamapper.security.User

Expand All @@ -40,6 +41,11 @@ class DataFlowJsonImporterService extends DataBindDataFlowImporterProviderServic
'4.0'
}

@Override
Boolean handlesContentType(String contentType) {
contentType.equalsIgnoreCase(DataFlowJsonExporterService.CONTENT_TYPE)
}

@Override
DataFlow importDataFlow(User currentUser, byte[] content) {
if (!currentUser) throw new ApiUnauthorizedException('JIS01', 'User must be logged in to import model')
Expand Down
Loading

0 comments on commit ff5dc5a

Please sign in to comment.