1+ /*
2+ * Licensed to the Apache Software Foundation (ASF) under one or more
3+ * contributor license agreements. See the NOTICE file distributed with
4+ * this work for additional information regarding copyright ownership.
5+ * The ASF licenses this file to You under the Apache License, Version 2.0
6+ * (the "License"); you may not use this file except in compliance with
7+ * the License. You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+ package org .apache .nifi .processors .graph ;
18+
19+ import org .apache .nifi .graph .GraphClientService ;
20+ import org .apache .nifi .json .JsonTreeReader ;
21+ import org .apache .nifi .processor .Processor ;
22+ import org .apache .nifi .serialization .record .Record ;
23+ import org .apache .nifi .serialization .RecordReader ;
24+ import org .apache .nifi .serialization .record .MockRecordWriter ;
25+ import org .apache .nifi .util .MockComponentLog ;
26+ import org .apache .nifi .util .MockFlowFile ;
27+ import org .apache .nifi .util .TestRunner ;
28+ import org .apache .nifi .util .TestRunners ;
29+ import org .junit .jupiter .api .BeforeEach ;
30+ import org .junit .jupiter .api .Test ;
31+
32+ import java .util .HashMap ;
33+ import java .util .Map ;
34+
35+ import static org .apache .nifi .processors .graph .EnrichGraphRecord .CLIENT_SERVICE ;
36+ import static org .apache .nifi .processors .graph .EnrichGraphRecord .IDENTIFIER_FIELD ;
37+ import static org .apache .nifi .processors .graph .EnrichGraphRecord .NODE_TYPE ;
38+ import static org .apache .nifi .processors .graph .EnrichGraphRecord .READER_SERVICE ;
39+ import static org .apache .nifi .processors .graph .EnrichGraphRecord .WRITER_SERVICE ;
40+ import static org .junit .jupiter .api .Assertions .assertEquals ;
41+ import static org .junit .jupiter .api .Assertions .fail ;
42+
43+ public class TestEnrichGraphRecord {
44+
45+ private TestRunner testRunner ;
46+ private JsonTreeReader reader ;
47+ private Processor processor ;
48+
49+ @ BeforeEach
50+ public void setup () throws Exception {
51+ processor = new EnrichGraphRecord ();
52+ testRunner = TestRunners .newTestRunner (processor );
53+
54+ GraphClientService mockGraphClientService = new MockCypherClientService ();
55+ MockRecordWriter writer = new MockRecordWriter ();
56+ reader = new JsonTreeReader ();
57+
58+ testRunner .setProperty (CLIENT_SERVICE , "graphClient" );
59+ testRunner .addControllerService ("graphClient" , mockGraphClientService );
60+ testRunner .addControllerService ("reader" , reader );
61+ testRunner .addControllerService ("writer" , writer );
62+ testRunner .setProperty (READER_SERVICE , "reader" );
63+ testRunner .setProperty (WRITER_SERVICE , "writer" );
64+ testRunner .enableControllerService (writer );
65+ testRunner .enableControllerService (reader );
66+ testRunner .enableControllerService (mockGraphClientService );
67+ }
68+
69+ @ Test
70+ public void testSuccessfulNodeProcessing () {
71+ Map <String , String > attributes = new HashMap <>();
72+ attributes .put ("id" , "123" );
73+
74+ String inputContent = "[{\" id\" : \" 123\" , \" name\" : \" Node1\" },{\" id\" : \" 789\" , \" name\" : \" Node2\" }]" ;
75+ testRunner .setProperty (IDENTIFIER_FIELD , "//id" );
76+ testRunner .setProperty ("name" , "//name" );
77+ testRunner .enqueue (inputContent .getBytes (), attributes );
78+
79+ testRunner .run ();
80+
81+ testRunner .assertTransferCount (EnrichGraphRecord .ORIGINAL , 1 );
82+ testRunner .assertTransferCount (EnrichGraphRecord .FAILURE , 0 );
83+ testRunner .assertTransferCount (EnrichGraphRecord .GRAPH , 2 );
84+
85+ MockFlowFile originalFlowFile = testRunner .getFlowFilesForRelationship (EnrichGraphRecord .ORIGINAL ).get (0 );
86+ assertEquals ("123" , originalFlowFile .getAttribute ("id" ));
87+ MockFlowFile successFlowFile = testRunner .getFlowFilesForRelationship (EnrichGraphRecord .GRAPH ).get (0 );
88+
89+ try {
90+ RecordReader recordReader = reader .createRecordReader (successFlowFile , successFlowFile .getContentStream (), new MockComponentLog ("1" , processor ));
91+ Record record = recordReader .nextRecord ();
92+ assertEquals ("John Smith" , record .getValue ("name" ));
93+ assertEquals (40 , record .getAsInt ("age" ));
94+ } catch (Exception e ) {
95+ fail ("Should not reach here" );
96+ }
97+ }
98+
99+ @ Test
100+ public void testSuccessfulEdgeProcessing () {
101+ Map <String , String > attributes = new HashMap <>();
102+ attributes .put ("id" , "123" );
103+
104+ String inputContent = "[{\" id\" : \" 123\" , \" name\" : \" Node1\" , \" relationship\" : \" ASSOCIATED_WITH\" }," +
105+ "{\" id\" : \" 789\" , \" name\" : \" Node2\" ,\" relationship\" : \" ASSOCIATED_WITH\" }]" ;
106+ testRunner .setProperty (IDENTIFIER_FIELD , "//relationship" );
107+ testRunner .setProperty ("name" , "//name" );
108+ testRunner .setProperty (NODE_TYPE , GraphClientService .EDGES_TYPE );
109+ testRunner .enqueue (inputContent .getBytes (), attributes );
110+
111+ testRunner .run ();
112+
113+ testRunner .assertTransferCount (EnrichGraphRecord .ORIGINAL , 1 );
114+ testRunner .assertTransferCount (EnrichGraphRecord .FAILURE , 0 );
115+ testRunner .assertTransferCount (EnrichGraphRecord .GRAPH , 2 );
116+
117+ MockFlowFile successFlowFile = testRunner .getFlowFilesForRelationship (EnrichGraphRecord .GRAPH ).get (0 );
118+
119+ try {
120+ RecordReader recordReader = reader .createRecordReader (successFlowFile , successFlowFile .getContentStream (), new MockComponentLog ("1" , processor ));
121+ Record record = recordReader .nextRecord ();
122+ assertEquals ("John Smith" , record .getValue ("name" ));
123+ assertEquals (40 , record .getAsInt ("age" ));
124+ assertEquals ("ASSOCIATED_WITH" , record .getValue ("relationship" ));
125+ } catch (Exception e ) {
126+ fail ("Should not reach here" );
127+ }
128+ }
129+
130+ @ Test
131+ public void testNullIdentifierValue () {
132+ Map <String , String > attributes = new HashMap <>();
133+ attributes .put ("id" , "123" );
134+
135+ // Two bad identifiers, one good
136+ String inputContent = "[{\" id\" : null, \" name\" : \" Node1\" },{\" id\" : null, \" name\" : \" Node2\" },{\" id\" : \" 123\" , \" name\" : \" Node3\" }]" ;
137+ testRunner .setProperty (IDENTIFIER_FIELD , "//id" );
138+ testRunner .setProperty ("name" , "//name" );
139+ testRunner .enqueue (inputContent .getBytes (), attributes );
140+
141+ testRunner .run ();
142+
143+ testRunner .assertTransferCount (EnrichGraphRecord .ORIGINAL , 0 );
144+ testRunner .assertTransferCount (EnrichGraphRecord .FAILURE , 1 );
145+ testRunner .assertTransferCount (EnrichGraphRecord .GRAPH , 1 );
146+
147+ // Verify 2 failed records
148+ MockFlowFile failedFlowFile = testRunner .getFlowFilesForRelationship (EnrichGraphRecord .FAILURE ).get (0 );
149+ assertEquals ("2" , failedFlowFile .getAttribute ("record.count" ));
150+ }
151+
152+ @ Test
153+ public void testFailedProcessing () {
154+ Map <String , String > attributes = new HashMap <>();
155+ attributes .put ("id" , "null" );
156+
157+ String inputContent = "[{\" id\" : null, \" name\" : \" Node1\" }]" ;
158+ testRunner .setProperty (IDENTIFIER_FIELD , "//id" );
159+ testRunner .setProperty ("name" , "//name" );
160+
161+ testRunner .enqueue (inputContent .getBytes (), attributes );
162+
163+ testRunner .run ();
164+
165+ testRunner .assertTransferCount (EnrichGraphRecord .ORIGINAL , 0 );
166+ testRunner .assertTransferCount (EnrichGraphRecord .FAILURE , 1 );
167+ testRunner .assertTransferCount (EnrichGraphRecord .GRAPH , 0 );
168+ }
169+ }
0 commit comments