NIFI-6069 Fixing fingerprinting of connection relationships to be properly sorted

This closes #3325.

Signed-off-by: Mark Payne <markap14@hotmail.com>
This commit is contained in:
Bryan Bende 2019-02-21 16:58:03 -05:00 committed by Mark Payne
parent 414bfc94fc
commit 26c00f1080
3 changed files with 68 additions and 49 deletions

View File

@ -614,7 +614,7 @@ public class FingerprintFactory {
// relationships
final NodeList relationshipElems = DomUtils.getChildNodesByTagName(connectionElem, "relationship");
final List<Element> sortedRelationshipElems = sortElements(relationshipElems, getConnectionRelationshipsComparator());
final List<Element> sortedRelationshipElems = sortElements(relationshipElems, getElementTextComparator());
for (final Element relationshipElem : sortedRelationshipElems) {
builder.append(getValue(relationshipElem, NO_VALUE));
}
@ -766,36 +766,7 @@ public class FingerprintFactory {
}
};
}
private Comparator<Element> getConnectionRelationshipsComparator() {
return getSingleChildComparator("relationship");
}
private Comparator<Element> getSingleChildComparator(final String childElementName) {
return new Comparator<Element>() {
@Override
public int compare(final Element e1, final Element e2) {
if (e2 == null) {
return -1;
} else if (e1 == null) {
return 1;
}
// compare using processor ids
final String e1Id = getFirstValue(DomUtils.getChildNodesByTagName(e1, childElementName));
if (e1Id == null) {
return 1;
}
final String e2Id = getFirstValue(DomUtils.getChildNodesByTagName(e2, childElementName));
if (e2Id == null) {
return -1;
}
return e1Id.compareTo(e2Id);
}
};
}
private Comparator<Element> getElementTextComparator() {
return new Comparator<Element>() {
@Override

View File

@ -16,24 +16,6 @@
*/
package org.apache.nifi.fingerprint;
import static org.apache.nifi.controller.serialization.ScheduledStateLookup.IDENTITY_LOOKUP;
import static org.apache.nifi.fingerprint.FingerprintFactory.FLOW_CONFIG_XSD;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.util.Optional;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.connectable.Position;
@ -55,6 +37,25 @@ import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Optional;
import static org.apache.nifi.controller.serialization.ScheduledStateLookup.IDENTITY_LOOKUP;
import static org.apache.nifi.fingerprint.FingerprintFactory.FLOW_CONFIG_XSD;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
*/
public class FingerprintFactoryTest {
@ -124,6 +125,13 @@ public class FingerprintFactoryTest {
assertNotEquals(fp1, fp2);
}
@Test
public void testConnectionWithMultipleRelationshipsSortedInFingerprint() throws IOException {
final String fingerprint = fingerprinter.createFingerprint(getResourceBytes("/nifi/fingerprint/flow-connection-with-multiple-rels.xml"), null);
assertNotNull(fingerprint);
assertTrue(fingerprint.contains("AAABBBCCCDDD"));
}
@Test
public void testSchemaValidation() throws IOException {
FingerprintFactory fp = new FingerprintFactory(null, getValidatingDocumentBuilder(), extensionManager);

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<flowController>
<maxThreadCount>15</maxThreadCount>
<rootGroup>
<connection>
<id>5bd05300-f03d-4511-a13f-6a36afe2bcc5</id>
<name/>
<bendPoints/>
<labelIndex>1</labelIndex>
<zIndex>0</zIndex>
<style/>
<sourceId>a65695bb-a938-4d3d-bf5d-f70a335268ec</sourceId>
<sourceGroupId>efeece05-3934-4298-a725-658eec116470</sourceGroupId>
<sourceType>OUTPUT_PORT</sourceType>
<destinationId>e520797a-dddb-4930-9034-2092d3e816a6</destinationId>
<destinationGroupId>e3909250-331d-420b-a9b3-cc54ad459401</destinationGroupId>
<destinationType>PROCESSOR</destinationType>
<relationship>CCC</relationship>
<relationship>BBB</relationship>
<relationship>DDD</relationship>
<relationship>AAA</relationship>
<maxWorkQueueSize>0</maxWorkQueueSize>
<flowFileExpiration>0 s</flowFileExpiration>
</connection>
</rootGroup>
</flowController>