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

GQL-31: Create a Mutation for Concept associations #102

Merged
merged 9 commits into from
Mar 21, 2024
Merged
183 changes: 141 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1027,64 +1027,163 @@ variables:
"ummVersion": "1.2.0"
}


#### Associations
For all supported arguments and columns, see [the schema](src/types/association.graphql).

The association support associate a Tool, Variable or Service record to a collation record.
##### Example Query

##### Associating a Tool to a Collection
Mutation CreateAssociation(
$conceptId: String!
$collectionConceptIds: [JSON]!
$conceptType: ConceptType!
){
createAssociation(
conceptId: $conceptId
collectionConceptIds: $collectionConceptIds
conceptType: $conceptType
) {
associatedItem
toolAssociation
}
}

variables:

{
"conceptId": "TL12000000-EXAMPLE",
"conceptType": "Tool",
"collectionConceptIds": [
{
"conceptId": "C12000000-EXAMPLE"
}
]
}

##### Associating a Variable to a Collection
Note for Variable association, nativeId and metadata are required params.

Mutation CreateAssociation(
$conceptId: String!
$collectionConceptIds: [JSON]!
$conceptType: ConceptType!
$nativeId: String
$metadata: JSON
){
createAssociation(
conceptId: $conceptId
collectionConceptIds: $collectionConceptIds
conceptType: $conceptType
nativeId: $nativeId
metadata: $metadata
) {
associatedItem
variableAssociation
}
}

variables:

{
"conceptId": "V12000000-EXAMPLE",
"conceptType": "Variable",
"collectionConceptIds": [
{
"conceptId": "C12000000-EXAMPLE"
}
],
"nativeId": "Variable native id",
"metadata": {}
}

##### Disassociation a Tool to a Collection (Delete)
Mutation DeleteAssociation(
$conceptId: String!
$collectionConceptIds: [JSON]!
$conceptType: ConceptType!
){
deleteAssociation(
conceptId: $conceptId
collectionConceptIds: $collectionConceptIds
conceptType: $conceptType
) {
associatedItem
toolAssociation
}
}

variables:

{
"conceptId": "TL12000000-EXAMPLE",
"conceptType": "Tool",
"collectionConceptIds": [
{
"conceptId": "C12000000-EXAMPLE"
}
]
}

##### Acls

For all supported arguments and columns, see [the schema](src/types/acl.graphql).

##### Example Query

query Acls($params: AclsInput) {
acls(params: $params) {
items {
acl
query Acls($params: AclsInput) {
acls(params: $params) {
items {
acl
}
}
}
}
}

variables:
variables:

{
"params": {
"includeFullAcl": true,
"pageNum": 1,
"pageSize": 20,
"permittedUser": "typical",
"target": "PROVIDER_CONTEXT"
}
}
{
"params": {
"includeFullAcl": true,
"pageNum": 1,
"pageSize": 20,
"permittedUser": "typical",
"target": "PROVIDER_CONTEXT"
}
}

##### Example Response

{
"data": {
"acls": {
"items": [
{
"acl": {
"group_permissions": [
{
"group_id": "AG1200000003-MMT_2",
"permissions": [
"read"
]
},
{
"group_id": "AG1200000001-CMR",
"permissions": [
"read"
]
{
"data": {
"acls": {
"items": [
{
"acl": {
"group_permissions": [
{
"group_id": "AG1200000003-MMT_2",
"permissions": [
"read"
]
},
{
"group_id": "AG1200000001-CMR",
"permissions": [
"read"
]
}
],
"provider_identity": {
"target": "PROVIDER_CONTEXT",
"provider_id": "MMT_2"
}
}
],
"provider_identity": {
"target": "PROVIDER_CONTEXT",
"provider_id": "MMT_2"
}
}
]
}
]
}
}
}
}

#### Local graph database:

Expand Down
147 changes: 147 additions & 0 deletions src/cmr/concepts/association.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { snakeCase } from 'lodash'
import { pickIgnoringCase } from '../../utils/pickIgnoringCase'
import Concept from './concept'
import { parseError } from '../../utils/parseError'
import { cmrVariableAssociation } from '../../utils/cmrVariableAssociation'
import { cmrAssociation } from '../../utils/cmrAssociation'
import { cmrDeleteAssociation } from '../../utils/cmrDeleteAssociation'

export default class Association extends Concept {
/**
* Parse and return the body of an create association operation
* @param {Object} ingestResponse HTTP response from the CMR endpoint
*/
parseAssociationBody(ingestResponse) {
const { data } = ingestResponse

return data[0]
}

/**
* Parses the response from an create association
* @param {Object} requestInfo Parsed data pertaining to the create operation
*/
async parseAssociationResponse(requestInfo) {
try {
const {
ingestKeys
} = requestInfo

const result = await this.getResponse()

const data = this.parseAssociationBody(result)

ingestKeys.forEach((key) => {
const cmrKey = snakeCase(key)

const { [cmrKey]: keyValue } = data

this.setIngestValue(key, keyValue)
})
} catch (e) {
parseError(e, { reThrowError: true })
}
}

/**
* Create the provided object into the CMR
* @param {Object} data Parameters provided by the query
* @param {Array} requestedKeys Keys requested by the query
* @param {Object} providedHeaders Headers requested by the query
*/
create(data, requestedKeys, providedHeaders) {
// Default headers
const defaultHeaders = {
'Content-Type': 'application/vnd.nasa.cmr.umm+json'
}

this.logKeyRequest(requestedKeys, 'association')

// Merge default headers into the provided headers and then pick out only permitted values
const permittedHeaders = pickIgnoringCase({
...defaultHeaders,
...providedHeaders
}, [
'Accept',
'Authorization',
'Client-Id',
'Content-Type',
'CMR-Request-Id'
])

this.response = cmrAssociation({
conceptType: this.getConceptType(),
data,
nonIndexedKeys: this.getNonIndexedKeys(),
headers: permittedHeaders
})
}

/**
* Create the provided object into the CMR
* @param {Object} data Parameters provided by the query
* @param {Array} requestedKeys Keys requested by the query
* @param {Object} providedHeaders Headers requested by the query
*/
createVariable(data, requestedKeys, providedHeaders) {
// Default headers
const defaultHeaders = {
'Content-Type': 'application/vnd.nasa.cmr.umm+json'
}

this.logKeyRequest(requestedKeys, 'association')

// Merge default headers into the provided headers and then pick out only permitted values
const permittedHeaders = pickIgnoringCase({
...defaultHeaders,
...providedHeaders
}, [
'Accept',
'Authorization',
'Client-Id',
'Content-Type',
'CMR-Request-Id'
])

this.response = cmrVariableAssociation({
conceptType: this.getConceptType(),
data,
nonIndexedKeys: this.getNonIndexedKeys(),
headers: permittedHeaders
})
}

/**
* Delete the provided object into the CMR
* @param {Object} data Parameters provided by the query
* @param {Array} requestedKeys Keys requested by the query
* @param {Object} providedHeaders Headers requested by the query
*/
deleteAssociation(data, requestedKeys, providedHeaders) {
// Default headers
const defaultHeaders = {
'Content-Type': 'application/vnd.nasa.cmr.umm+json'
}

this.logKeyRequest(requestedKeys, 'association')

// Merge default headers into the provided headers and then pick out only permitted values
const permittedHeaders = pickIgnoringCase({
...defaultHeaders,
...providedHeaders
}, [
'Accept',
'Authorization',
'Client-Id',
'Content-Type',
'CMR-Request-Id'
])

this.response = cmrDeleteAssociation({
conceptType: this.getConceptType(),
data,
nonIndexedKeys: this.getNonIndexedKeys(),
headers: permittedHeaders
})
}
}
Loading
Loading