Skip to content

Commit

Permalink
Merge pull request #634 from JupiterOne/633-class-label
Browse files Browse the repository at this point in the history
Fix #633 - Support `_class` as a node label property
  • Loading branch information
adam-in-ict authored Feb 22, 2022
2 parents 1504c54 + 685e469 commit 3f602d0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,33 @@ and this project adheres to

## Unreleased

### Added

- [#633](https://github.com/JupiterOne/sdk/issues/633) Support `_class` as a
node label property for entities created by the Neo4j store.

Example query by `_type`:

```cy
MATCH (account:github_account)-[OWNS]->
(repo:github_repo)-[ALLOWS]->
(user:github_user {
role:"OUTSIDE"
})
RETURN account, repo, user
```

Example query by `_class`:

```cy
MATCH (account:Account)-[OWNS]->
(repo:CodeRepo)-[ALLOWS]->
(user:User {
role:"OUTSIDE"
})
RETURN account, repo, user
```

## [8.4.2] - 2022-02-19

### Fixed
Expand Down
31 changes: 26 additions & 5 deletions packages/integration-sdk-cli/src/neo4j/neo4jGraphStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Entity, Relationship } from '@jupiterone/integration-sdk-core';
import { sanitizeValue, buildPropertyParameters } from './neo4jUtilities';
import {
sanitizeValue,
buildPropertyParameters,
sanitizePropertyName,
} from './neo4jUtilities';

import * as neo4j from 'neo4j-driver';

Expand Down Expand Up @@ -51,20 +55,33 @@ export class Neo4jGraphStore {
async addEntities(newEntities: Entity[]) {
const nodeAlias: string = 'entityNode';
for (const entity of newEntities) {
//Add index if not already in types. This will optimize future
//MATCH/MERGE calls.
let classLabels = '';
if (entity._class) {
if (typeof entity._class === 'string') {
classLabels += `:${sanitizePropertyName(entity._class)}`;
} else {
for (const className of entity._class) {
classLabels += `:${sanitizePropertyName(className)}`;
}
}
}
// I believe we currently can't use parameters for node labels, hence the use of string
// interpolation in the below commands.
// Add index if not already in types. This will optimize future
// MATCH/MERGE calls.
if (!this.typeList.has(entity._type)) {
await this.runCypherCommand(
`CREATE INDEX index_${entity._type} IF NOT EXISTS FOR (n:${entity._type}) ON (n._key, n._integrationInstanceID);`,
);
this.typeList.add(entity._type);
}
const sanitizedType = sanitizePropertyName(entity._type);
const propertyParameters = buildPropertyParameters(entity);
const finalKeyValue = sanitizeValue(entity._key.toString());
const buildCommand = `
MERGE (${nodeAlias} {_key: $finalKeyValue, _integrationInstanceID: $integrationInstanceID})
SET ${nodeAlias} += $propertyParameters
SET ${nodeAlias}:${entity._type};`;
SET ${nodeAlias}:${sanitizedType}${classLabels};`;
await this.runCypherCommand(buildCommand, {
propertyParameters: propertyParameters,
finalKeyValue: finalKeyValue,
Expand Down Expand Up @@ -118,10 +135,14 @@ export class Neo4jGraphStore {
);
}

const sanitizedRelationshipClass = sanitizePropertyName(
relationship._class,
);

const buildCommand = `
MERGE (start {_key: $startEntityKey, _integrationInstanceID: $integrationInstanceID})
MERGE (end {_key: $endEntityKey, _integrationInstanceID: $integrationInstanceID})
MERGE (start)-[${relationshipAlias}:${relationship._class}]->(end)
MERGE (start)-[${relationshipAlias}:${sanitizedRelationshipClass}]->(end)
SET ${relationshipAlias} += $propertyParameters;`;
await this.runCypherCommand(buildCommand, {
propertyParameters: propertyParameters,
Expand Down

0 comments on commit 3f602d0

Please sign in to comment.