Skip to content
This repository has been archived by the owner on Apr 24, 2018. It is now read-only.

Commit

Permalink
Merge pull request #6 from Financial-Times/handle-identifiers
Browse files Browse the repository at this point in the history
Handle identifiers, added coveralls
  • Loading branch information
nwrigh committed Jan 20, 2017
2 parents 3f735c1 + da65e16 commit b112fb0
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 82 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ Compiled source #
# Logs and databases #
######################
*.log


*.idea
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Industry Classification Reader/Writer for Neo4j (industry-classification-rw-neo4j)

[![Circle CI](https://circleci.com/gh/Financial-Times/industry-classifications-rw-neo4j.svg?style=shield)](https://circleci.com/gh/Financial-Times/industry-classifications-rw-neo4j)[![Go Report Card](https://goreportcard.com/badge/github.com/Financial-Times/industry-classifications-rw-neo4j)](https://goreportcard.com/report/github.com/Financial-Times/industry-classifications-rw-neo4j) [![Coverage Status](https://coveralls.io/repos/github/Financial-Times/industry-classifications-rw-neo4j/badge.svg)](https://coveralls.io/github/Financial-Times/industry-classifications-rw-neo4j)

__An API for reading/writing industry classification into Neo4j. Expects the industry classification json supplied to be in the following format:

{"uuid":"e8f669e0-e72f-3416-ad0c-09823ec6a27f", "prefLabel":"Industrial Machinery"}
Expand Down Expand Up @@ -64,12 +65,12 @@ Thie internal read should return what got written (i.e., there isn't a public re

If not found, you'll get a 404 response.

Empty fields are omitted from the response.
`curl -H "X-Request-Id: 123" localhost:8080/industryclassification/e8f669e0-e72f-3416-ad0c-09823ec6a27f`
Empty fields are omitted from the response.46d1741e-8075-3a4a-872c-71d8130fcb71
`curl -H "X-Request-Id: 123" localhost:8080/industryclassifications/e8f669e0-e72f-3416-ad0c-09823ec6a27f`

### DELETE
Will return 204 if successful, 404 if not found
`curl -XDELETE -H "X-Request-Id: 123" localhost:8080/industryclassification/e8f669e0-e72f-3416-ad0c-09823ec6a27f`
`curl -XDELETE -H "X-Request-Id: 123" localhost:8080/industryclassifications/e8f669e0-e72f-3416-ad0c-09823ec6a27f`

### Admin endpoints
Healthchecks: [http://localhost:8080/__health](http://localhost:8080/__health)
Expand Down
15 changes: 15 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,22 @@ machine:
- neo4j
environment:
NEO4J_TEST_URL: http://neo4j:x@localhost:7474/db/data/
_JAVA_OPTIONS: "-Xms512m -Xmx1024m"

dependencies:
pre:
- go get github.com/axw/gocov/gocov; go get github.com/matm/gocov-html; go get -u github.com/jstemmer/go-junit-report
test:
pre:
- go get github.com/mattn/goveralls
- 'curl -u neo4j:neo4j -H "Content-Type: application/json" -X POST -d ''{"password":"x"}'' http://localhost:7474/user/neo4j/password'
override:
- mkdir -p $CIRCLE_TEST_REPORTS/golang
- go test -race -v ./... | go-junit-report > $CIRCLE_TEST_REPORTS/golang/junit.xml
- go list ./... | awk -F/ '{print $4}' | xargs -I {} go test -v -cover -race -coverprofile=$CIRCLE_ARTIFACTS/{}.out ./{}
- cd $CIRCLE_ARTIFACTS && sed -i '1d' *.out
- |
echo "mode: atomic" > $CIRCLE_ARTIFACTS/overall-coverage.result
- cd $CIRCLE_ARTIFACTS && cat *.out >> overall-coverage.result
post:
- goveralls -coverprofile=$CIRCLE_ARTIFACTS/overall-coverage.result -service=circle-ci -repotoken=$COVERALLS_TOKEN
Binary file added industry-classifications-rw-neo4j
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"uuid": "f9694ba7-eab0-4ce0-8e01-ff64bccb813c",
"properName": "NIKE, Inc.",
"prefLabel": "NIKE, Inc.",
"alternativeIdentifiers": {
"factsetIdentifier": "000RBW-E",
"uuids": ["f9694ba7-eab0-4ce0-8e01-ff64bccb813c"],
"leiCode": "787RXPR0UX0O0XUXPZ81"
},
"industryClassification": "f21a5cc0-d326-4e62-b84a-d840c2209fee",
"shortName": "NIKE",
"legalName": "NIKE, Inc.",
"formerNames": [
"Blue Ribbon Sports"
],
"hiddenLabel": "NIKE INC",
"type": "PublicCompany",
"aliases": [
"Nike",
"NIKE",
"Nike Incorporated",
"Nike Inc",
"NIKE, Inc.",
"Blue Ribbon Sports"
]
}
73 changes: 49 additions & 24 deletions industryclassifications/industry_classifications_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package industryclassifications

import (
"encoding/json"

"github.com/Financial-Times/neo-utils-go/neoutils"
"github.com/jmcvetta/neoism"
)
Expand All @@ -20,7 +19,12 @@ func NewCypherIndustryClassifcationService(cypherRunner neoutils.NeoConnection)
//Initialise initialisation of the indexes
func (s service) Initialise() error {
return s.conn.EnsureConstraints(map[string]string{
"IndustryClassification": "uuid"})
"Thing": "uuid",
"Concept": "uuid",
"Classification": "uuid",
"IndustryClassification": "uuid",
"FactsetIdentifier": "value",
"UPPIdentifier": "value"})
}

// Check - Feeds into the Healthcheck and checks whether we can connect to Neo and that the datastore isn't empty
Expand All @@ -31,13 +35,15 @@ func (s service) Check() error {
// Read - reads a industry Classification given a UUID
func (s service) Read(uuid string) (interface{}, bool, error) {
results := []struct {
UUID string `json:"uuid"`
PrefLabel string `json:"prefLabel"`
UUID string `json:"uuid"`
PrefLabel string `json:"prefLabel"`
UUIDs []string `json:"uuids"`
}{}

query := &neoism.CypherQuery{
Statement: `MATCH (n:IndustryClassification {uuid:{uuid}}) return n.uuid
as uuid, n.prefLabel as prefLabel`,
Statement: `MATCH (n:IndustryClassification {uuid:{uuid}})
OPTIONAL MATCH (upp:UPPIdentifier)-[:IDENTIFIES]->(n)
RETURN n.uuid as uuid, n.prefLabel as prefLabel, collect(upp.value) as uuids`,
Parameters: map[string]interface{}{
"uuid": uuid,
},
Expand Down Expand Up @@ -65,37 +71,55 @@ func (s service) Read(uuid string) (interface{}, bool, error) {

//Write - Writes a industry classification node
func (s service) Write(thing interface{}) error {
r := thing.(industryClassification)
industryToWrite := thing.(industryClassification)

params := map[string]interface{}{
"uuid": r.UUID,
}

if r.PrefLabel != "" {
params["prefLabel"] = r.PrefLabel
//cleanUP all the previous IDENTIFIERS referring to that uuid
deletePreviousIdentifiersQuery := &neoism.CypherQuery{
Statement: ` MATCH (t:Thing {uuid:{uuid}})
OPTIONAL MATCH (t)<-[iden:IDENTIFIES]-(i)
DELETE iden, i`,
Parameters: map[string]interface{}{
"uuid": industryToWrite.UUID,
},
}

statement := `MERGE (n:Thing {uuid: {uuid}})
//create-update node for IndustryClassification
createIndustryClassficationQuery := &neoism.CypherQuery{
Statement: ` MERGE (n:Thing {uuid: {uuid}})
set n={allprops}
set n :IndustryClassification:Classification:Concept`
set n :IndustryClassification:Classification:Concept`,
Parameters: map[string]interface{}{
"uuid": industryToWrite.UUID,
"allprops": map[string]interface{}{
"uuid": industryToWrite.UUID,
"prefLabel": industryToWrite.PrefLabel,
},
},
}

query := &neoism.CypherQuery{
Statement: statement,
queryBatch := []*neoism.CypherQuery{deletePreviousIdentifiersQuery, createIndustryClassficationQuery}

identQuery := &neoism.CypherQuery{
Statement: ` MERGE (t:Thing {uuid:{uuid}})
CREATE (i:Identifier {value:{uuid}})-[:IDENTIFIES]->(t)
set i :Identifier:UPPIdentifier`,
Parameters: map[string]interface{}{
"uuid": r.UUID,
"allprops": params,
"uuid": industryToWrite.UUID,
},
}

return s.conn.CypherBatch([]*neoism.CypherQuery{query})
queryBatch = append(queryBatch, identQuery)

return s.conn.CypherBatch(queryBatch)
}

//Delete - Deletes a Role
func (s service) Delete(uuid string) (bool, error) {
clearNode := &neoism.CypherQuery{
Statement: `
MATCH (p:Thing {uuid: {uuid}})
REMOVE p:Concept
REMOVE p:IndustryClassification
SET p={props}
`,
Expand All @@ -110,11 +134,12 @@ func (s service) Delete(uuid string) (bool, error) {

removeNodeIfUnused := &neoism.CypherQuery{
Statement: `
MATCH (p:Thing {uuid: {uuid}})
OPTIONAL MATCH (p)-[a]-(x)
WITH p, count(a) AS relCount
WHERE relCount = 0
DELETE p
MATCH (thing:Thing {uuid: {uuid}})
OPTIONAL MATCH (thing)-[ir:IDENTIFIES]-(id:Identifier)
OPTIONAL MATCH (thing)-[a]-(x:Thing)
WITH ir, id, thing, count(a) AS relCount
WHERE relCount = 0
DELETE ir, id, thing
`,
Parameters: map[string]interface{}{
"uuid": uuid,
Expand Down

0 comments on commit b112fb0

Please sign in to comment.