diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/pom.xml b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/pom.xml index c1a8b0a82d..7ea4cc4281 100644 --- a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/pom.xml +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/pom.xml @@ -141,6 +141,14 @@ src/test/resources/examples/basic-types.dat src/test/resources/examples/composite.dat src/test/resources/examples/tbcd-string.dat + src/test/resources/test_hugging_comment.asn + src/test/resources/test_version_bracket.asn + src/test/resources/test_constraints.asn + src/test/resources/test_complex_for_preprocessing.asn + src/test/resources/preprocessed_test_hugging_comment.asn + src/test/resources/preprocessed_test_version_bracket.asn + src/test/resources/preprocessed_test_constraints.asn + src/test/resources/preprocessed_test_complex_for_preprocessing.asn diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/JASN1Reader.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/JASN1Reader.java index c2bbd99761..ba40f45b78 100644 --- a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/JASN1Reader.java +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/JASN1Reader.java @@ -29,6 +29,7 @@ import org.apache.nifi.annotation.documentation.Tags; import org.apache.nifi.annotation.lifecycle.OnDisabled; import org.apache.nifi.annotation.lifecycle.OnEnabled; import org.apache.nifi.components.AbstractConfigurableComponent; +import org.apache.nifi.components.AllowableValue; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.PropertyValue; import org.apache.nifi.components.ValidationContext; @@ -36,12 +37,10 @@ import org.apache.nifi.components.ValidationResult; import org.apache.nifi.controller.ConfigurationContext; import org.apache.nifi.controller.ControllerServiceInitializationContext; import org.apache.nifi.expression.ExpressionLanguageScope; +import org.apache.nifi.jasn1.preprocess.AsnPreprocessorEngine; import org.apache.nifi.logging.ComponentLog; import org.apache.nifi.processor.exception.ProcessException; import org.apache.nifi.processor.util.StandardValidators; -import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.schema.access.SchemaNotFoundException; -import org.apache.nifi.serialization.MalformedRecordException; import org.apache.nifi.serialization.RecordReader; import org.apache.nifi.serialization.RecordReaderFactory; import org.apache.nifi.util.file.classloader.ClassLoaderUtils; @@ -134,16 +133,51 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record .required(false) .build(); + private static final AllowableValue DEFAULT = new AllowableValue( + "DEFAULT", + "Default", + "No additional preprocessing should occur, use original schema." + ); + + private static final AllowableValue ADDITIONAL_PREPROCESSING = new AllowableValue( + "ADDITIONAL_PREPROCESSING", + "Additional Preprocessing", + "Perform additional preprocessing, resulting in potentially modified schema. (See additional details for more information.)" + ); + + private static final PropertyDescriptor SCHEMA_PREPARATION_STRATEGY = new PropertyDescriptor.Builder() + .name("Schema Preparation Strategy") + .description("When set, NiFi will do additional preprocessing steps that creates modified versions of the provided ASN files," + + " removing unsupported features in a way that makes them less strict but otherwise should still be compatible with incoming data." + + " The original files will remain intact and new ones will be created with the same names in the directory defined in the 'Additional Preprocessing Output Directory' property." + + " For more information about these additional preprocessing steps please see Additional Details - Additional Preprocessing.") + .allowableValues(DEFAULT, ADDITIONAL_PREPROCESSING) + .required(true) + .defaultValue(DEFAULT.getValue()) + .build(); + + private static final PropertyDescriptor SCHEMA_PREPARATION_DIRECTORY = new PropertyDescriptor.Builder() + .name("Schema Preparation Directory") + .description("When the processor is configured to do additional preprocessing, new modified schema files will be created in this directory." + + " For more information about additional preprocessing please see description of the 'Do Additional Preprocessing' property or Additional Details - Additional Preprocessing.") + .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY) + .addValidator(StandardValidators.createDirectoryExistsValidator(true, false)) + .dependsOn(SCHEMA_PREPARATION_STRATEGY, ADDITIONAL_PREPROCESSING) + .required(true) + .build(); + private final List propertyDescriptors = Arrays.asList( ROOT_MODEL_NAME, ROOT_CLASS_NAME, - ASN_FILES + ASN_FILES, + SCHEMA_PREPARATION_STRATEGY, + SCHEMA_PREPARATION_DIRECTORY ); private String identifier; ComponentLog logger; - private RecordSchemaProvider schemaProvider = new RecordSchemaProvider(); + private final RecordSchemaProvider schemaProvider = new RecordSchemaProvider(); volatile Path asnOutDir; private volatile PropertyValue rootModelNameProperty; @@ -159,7 +193,7 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record } @Override - public void initialize(ControllerServiceInitializationContext context) throws InitializationException { + public void initialize(ControllerServiceInitializationContext context) { identifier = context.getIdentifier(); logger = context.getLogger(); } @@ -175,7 +209,7 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record results.add(new ValidationResult.Builder() .subject(ROOT_MODEL_NAME.getName()) .valid(false) - .explanation("Onle one of '" + ROOT_MODEL_NAME.getDisplayName() + "' or '" + ROOT_CLASS_NAME.getDisplayName() + "' should be set!") + .explanation("Only one of '" + ROOT_MODEL_NAME.getDisplayName() + "' or '" + ROOT_CLASS_NAME.getDisplayName() + "' should be set!") .build()); } @@ -191,12 +225,25 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record } @OnEnabled - public void onEnabled(final ConfigurationContext context) throws InitializationException { + public void onEnabled(final ConfigurationContext context) { if (context.getProperty(ASN_FILES) != null && context.getProperty(ASN_FILES).isSet()) { - String[] asnFilesPaths = Arrays.stream(context.getProperty(ASN_FILES).evaluateAttributeExpressions().getValue().split(",")) - .map(String::trim) - .toArray(String[]::new); + String asnFilesString = context.getProperty(ASN_FILES).evaluateAttributeExpressions().getValue(); + if (ADDITIONAL_PREPROCESSING.getValue().equals(context.getProperty(SCHEMA_PREPARATION_STRATEGY).getValue())) { + final AsnPreprocessorEngine asnPreprocessorEngine = new AsnPreprocessorEngine(); + + final String preprocessOutputDirectory = context.getProperty(SCHEMA_PREPARATION_DIRECTORY).evaluateAttributeExpressions().getValue(); + + asnFilesString = asnPreprocessorEngine.preprocess( + logger, + asnFilesString, + preprocessOutputDirectory + ); + } + + final String[] asnFilesPaths = Arrays.stream(asnFilesString.split(",")) + .map(String::trim) + .toArray(String[]::new); compileAsnToClass(asnFilesPaths); } @@ -211,7 +258,7 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record customClassLoader = this.getClass().getClassLoader(); } } catch (final Exception ex) { - logger.error("Couldn't create classloader for compiled classes.", ex); + logger.error("Could not create ClassLoader for compiled ASN.1 classes", ex); } rootModelNameProperty = context.getProperty(ROOT_MODEL_NAME); @@ -223,18 +270,10 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record private void compileAsnToClass(String... asnFilePaths) { try { asnOutDir = Files.createTempDirectory(getIdentifier() + "_asn_"); - - logger.info("ASN files will be compiled to '" + asnOutDir + "'"); } catch (IOException e) { - throw new ProcessException("Couldn't create temporary directory for compiled asn files.", e); + throw new ProcessException("Could not create temporary directory for compiled ASN.1 files", e); } - List asnCompilerArguments = new ArrayList<>(); - asnCompilerArguments.add("-f"); - asnCompilerArguments.addAll(Arrays.asList(asnFilePaths)); - asnCompilerArguments.add("-o"); - asnCompilerArguments.add(asnOutDir.toString()); - HashMap modulesByName = new HashMap<>(); Exception parseException = null; @@ -295,12 +334,12 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record Boolean success = task.call(); if (!success) { - Set errorMessages = new LinkedHashSet(); + Set errorMessages = new LinkedHashSet<>(); diagnosticListener.getDiagnostics().stream().map(d -> d.getMessage(Locale.getDefault())).forEach(errorMessages::add); errorMessages.forEach(logger::error); - throw new ProcessException("Java compilation failed"); + throw new ProcessException("ASN.1 Java compilation failed"); } } @@ -333,7 +372,7 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record InputStream in, long inputLength, ComponentLog logger - ) throws MalformedRecordException, IOException, SchemaNotFoundException { + ) { final String rootClassName; if (rootModelNameProperty != null && rootModelNameProperty.isSet()) { rootClassName = guessRootClassName(rootModelNameProperty.evaluateAttributeExpressions(variables).getValue()); @@ -366,13 +405,13 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record } }; + AsnModel model = new AsnModel(); + parser.module_definitions(model); + if (parseError.get()) { throw new ProcessException("ASN.1 parsing failed"); } - AsnModel model = new AsnModel(); - parser.module_definitions(model); - return model; } @@ -390,7 +429,7 @@ public class JASN1Reader extends AbstractConfigurableComponent implements Record return rootClassNameBuilder.toString(); } catch (Exception e) { - throw new ProcessException("Couldn't infer root model name from '" + rootModelName + "'", e); + throw new ProcessException("Could not infer root model name from '" + rootModelName + "'", e); } } } diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessor.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessor.java new file mode 100644 index 0000000000..d58a5b4f02 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessor.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess; + +import java.util.List; + +public interface AsnPreprocessor { + List preprocessAsn(List lines); +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngine.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngine.java new file mode 100644 index 0000000000..7a3d82e465 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngine.java @@ -0,0 +1,105 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess; + +import org.apache.nifi.jasn1.preprocess.preprocessors.ConstraintAsnPreprocessor; +import org.apache.nifi.jasn1.preprocess.preprocessors.HuggingCommentAsnPreprocessor; +import org.apache.nifi.jasn1.preprocess.preprocessors.VersionBracketAsnPreprocessor; +import org.apache.nifi.logging.ComponentLog; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +public class AsnPreprocessorEngine { + public static final String COMMA = "\\s*,\\s*"; + + private static final List PREPROCESSORS = Arrays.asList( + new HuggingCommentAsnPreprocessor(), + new VersionBracketAsnPreprocessor(), + new ConstraintAsnPreprocessor() + ); + + public String preprocess( + ComponentLog componentLog, + String asnFilesString, + String outputDirectory + ) { + final String[] inputFiles = asnFilesString.split(COMMA); + + final StringJoiner preprocessedInputFiles = new StringJoiner(","); + + for (String inputFile : inputFiles) { + final Path inputFilePath = Paths.get(inputFile); + final Path fileName = inputFilePath.getFileName(); + + final List lines = readAsnLines(componentLog, inputFile, inputFilePath); + + final List preprocessedLines = preprocessAsn(lines); + + final String preprocessedAsn = preprocessedLines + .stream() + .collect(Collectors.joining(System.lineSeparator())); + + final Path preprocessedAsnPath = Paths.get(outputDirectory, fileName.toString()); + preprocessedInputFiles.add(preprocessedAsnPath.toString()); + + writePreprocessedAsn(componentLog, preprocessedAsn, preprocessedAsnPath); + } + + return preprocessedInputFiles.toString(); + } + + List preprocessAsn(List lines) { + List preprocessedAsn = lines; + + for (AsnPreprocessor preprocessor : getPreprocessors()) { + preprocessedAsn = preprocessor.preprocessAsn(preprocessedAsn); + } + + return preprocessedAsn; + } + + List readAsnLines(ComponentLog componentLog, String inputFile, Path inputFilePath) { + List lines; + try { + lines = Files.readAllLines(inputFilePath); + } catch (IOException e) { + throw new UncheckedIOException(String.format("Read ASN.1 Schema failed [%s]", inputFile), e); + } + return lines; + } + + void writePreprocessedAsn(ComponentLog componentLog, String preprocessedAsn, Path preprocessedAsnPath) { + try { + Files.write(preprocessedAsnPath, preprocessedAsn.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new UncheckedIOException(String.format("Write ASN.1 Schema failed [%s]", preprocessedAsnPath), e); + } + } + + List getPreprocessors() { + return PREPROCESSORS; + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessor.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessor.java new file mode 100644 index 0000000000..1d3fd8eb5c --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessor.java @@ -0,0 +1,91 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.apache.nifi.jasn1.preprocess.AsnPreprocessor; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ConstraintAsnPreprocessor implements AsnPreprocessor { + public static final String OPEN_BRACKET = "("; + public static final String CLOSE_BRACKET = ")"; + + public static final Pattern ALLOWED = Pattern.compile("^(\\d+\\))(.*)"); + + @Override + public List preprocessAsn(List lines) { + final List preprocessedLines = new ArrayList<>(); + + final AtomicInteger unclosedCounter = new AtomicInteger(0); + lines.forEach(line -> { + final StringBuilder preprocessedLine = new StringBuilder(); + + String contentToProcess = line; + + while (contentToProcess.contains(OPEN_BRACKET) || contentToProcess.contains(CLOSE_BRACKET)) { + if (contentToProcess.matches("^\\s*--.*$")) { + break; + } + + final int openBracketIndex = contentToProcess.indexOf(OPEN_BRACKET); + final int closeBracketIndex = contentToProcess.indexOf(CLOSE_BRACKET); + + if (openBracketIndex != -1 && (openBracketIndex < closeBracketIndex) || closeBracketIndex == -1) { + final String contentBeforeOpenBracket = contentToProcess.substring(0, openBracketIndex); + final String contentAfterOpenBracket = contentToProcess.substring(openBracketIndex + 1); + + if (unclosedCounter.get() < 1) { + if (!contentBeforeOpenBracket.isEmpty()) { + preprocessedLine.append(contentBeforeOpenBracket + " "); + // Adding a space " " because (...) blocks can serve as separators so removing them might + // join together parts that should stay separated + } + + final Matcher supportedMatcher = ALLOWED.matcher(contentAfterOpenBracket); + if (supportedMatcher.matches()) { + preprocessedLine.append(OPEN_BRACKET + supportedMatcher.group(1)); + contentToProcess = supportedMatcher.group(2); + continue; + } + } + + unclosedCounter.incrementAndGet(); + + contentToProcess = contentAfterOpenBracket; + } else if (closeBracketIndex != -1) { + unclosedCounter.decrementAndGet(); + + contentToProcess = contentToProcess.substring(closeBracketIndex + 1); + } + } + + if (unclosedCounter.get() < 1) { + if (!contentToProcess.isEmpty()) { + preprocessedLine.append(contentToProcess); + } + } + + preprocessedLines.add(preprocessedLine.toString()); + }); + + return preprocessedLines; + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessor.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessor.java new file mode 100644 index 0000000000..8667f46e30 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessor.java @@ -0,0 +1,49 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.apache.nifi.jasn1.preprocess.AsnPreprocessor; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class HuggingCommentAsnPreprocessor implements AsnPreprocessor { + public static final Pattern HUGGING_COMMENT_PATTERN = Pattern.compile("^(.*[^\\s])(--.*)$"); + + @Override + public List preprocessAsn(List lines) { + final List preprocessedLines = new ArrayList<>(); + + lines.forEach(line -> { + final StringBuilder preprocessedLine = new StringBuilder(); + + final Matcher huggingCommentMather = HUGGING_COMMENT_PATTERN.matcher(line); + if (huggingCommentMather.matches()) { + preprocessedLine.append(huggingCommentMather.group(1)) + .append(" ") + .append(huggingCommentMather.group(2)); + preprocessedLines.add(preprocessedLine.toString()); + } else { + preprocessedLines.add(line); + } + }); + + return preprocessedLines; + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessor.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessor.java new file mode 100644 index 0000000000..ca976de535 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessor.java @@ -0,0 +1,89 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.apache.nifi.jasn1.preprocess.AsnPreprocessor; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Pattern; + +public class VersionBracketAsnPreprocessor implements AsnPreprocessor { + public static final String OPEN_VERSION_BRACKET = "[["; + public static final String CLOSE_VERSION_BRACKET = "]]"; + + public static final Pattern ONLY_WHITESPACES = Pattern.compile("^\\s*$"); + public static final Pattern ONLY_COMMENT = Pattern.compile("^\\s*--.*$"); + public static final Pattern IS_OPTIONAL_ALREADY = Pattern.compile(".*OPTIONAL\\s*,?\\s*$"); + + public static final String TRAILING_COMMA_WITH_POTENTIAL_WHITESPACES = "(\\s*)(,?)(\\s*)$"; + public static final String ADD_OPTIONAL = " OPTIONAL$1$2$3"; + + @Override + public List preprocessAsn(List lines) { + final List preprocessedLines = new ArrayList<>(); + + final AtomicBoolean inVersionBracket = new AtomicBoolean(false); + lines.forEach(line -> { + final StringBuilder preprocessedLine = new StringBuilder(); + String contentToProcess = line; + + final int versionBracketStart = contentToProcess.indexOf(OPEN_VERSION_BRACKET); + if (versionBracketStart > -1) { + inVersionBracket.set(true); + + final String contentBeforeVersionBracket = line.substring(0, versionBracketStart); + if (!contentBeforeVersionBracket.isEmpty()) { + preprocessedLine.append(contentBeforeVersionBracket); + } + + contentToProcess = contentToProcess.substring(versionBracketStart + 2); + } + + final int versionBracketEnd = contentToProcess.indexOf(CLOSE_VERSION_BRACKET); + String contentAfterVersionBracket = null; + if (versionBracketEnd > -1) { + contentAfterVersionBracket = contentToProcess.substring(versionBracketEnd + 2); + contentToProcess = contentToProcess.substring(0, versionBracketEnd); + } + + if (inVersionBracket.get() + && !ONLY_WHITESPACES.matcher(contentToProcess).matches() + && !ONLY_COMMENT.matcher(contentToProcess).matches() + && !IS_OPTIONAL_ALREADY.matcher(contentToProcess).matches() + ) { + contentToProcess = contentToProcess.replaceFirst(TRAILING_COMMA_WITH_POTENTIAL_WHITESPACES, ADD_OPTIONAL); + } + + if (!contentToProcess.isEmpty()) { + preprocessedLine.append(contentToProcess); + } + + if (contentAfterVersionBracket != null) { + if (!contentAfterVersionBracket.isEmpty()) { + preprocessedLine.append(contentAfterVersionBracket); + } + inVersionBracket.set(false); + } + + preprocessedLines.add(preprocessedLine.toString()); + }); + + return preprocessedLines; + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/resources/docs/org.apache.nifi.jasn1.JASN1Reader/additionalDetails.html b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/resources/docs/org.apache.nifi.jasn1.JASN1Reader/additionalDetails.html index 31edf6d64e..51ca11fdd9 100644 --- a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/resources/docs/org.apache.nifi.jasn1.JASN1Reader/additionalDetails.html +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/main/resources/docs/org.apache.nifi.jasn1.JASN1Reader/additionalDetails.html @@ -122,5 +122,62 @@

+ +

Additional Preprocessing

+ +

+ NiFi doesn't support every feature that the ASN standard allows. To alleviate problems when encountering ASN files with unsupported features, + NiFi can do additional preprocessing steps that creates modified versions of the provided ASN files, + removing unsupported features in a way that makes them less strict but otherwise should still be compatible with incoming data. + This feature can be switched on via the 'Do Additional Preprocessing' property. + The original files will remain intact and new ones will be created with the same names in a directory set in the 'Additional Preprocessing Output Directory' property. + Please note that this is a best-effort attempt. It is also strongly recommended to compare the resulting ASN files to the originals and make sure they are still appropriate. +
+
+ The following modification are applied: +

    +
  1. + Constraints - Advanced constraints are not recognized as valid ASN elements by NiFi. This step will try to remove all types of constraints. +
    E.g. +
    field   [3] INTEGER(SIZE(1..8,...,10|12|20)) OPTIONAL
    + will be changed to +
    field   [3] INTEGER  OPTIONAL
    +
  2. +
  3. + Version brackets - NiFi will try to remove all version brackets and leave all defined fields as OPTIONAL. +
    E.g. +
    +MyType ::= SEQUENCE {
    +	integerField1		INTEGER,
    +	integerField2		INTEGER,
    +	...,	-- comment1
    +[[ -- comment2
    +	integerField3		INTEGER,
    +	integerField4		INTEGER,
    +	integerField5		INTEGER ]]
    +}
    +                    
    + will be changed to +
    +MyType ::= SEQUENCE {
    +	integerField1		INTEGER,
    +	integerField2		INTEGER,
    +	...,	-- comment1
    + -- comment2
    +	integerField3		INTEGER OPTIONAL,
    +	integerField4		INTEGER OPTIONAL,
    +	integerField5		INTEGER OPTIONAL
    +}
    +                    
    +
  4. +
  5. + "Hugging" comments - This is not really an ASN feature but a potential error. The double dash comment indicator "--" should be separated from ASN elements. +
    E.g. +
    field   [0] INTEGER(1..8)--comment
    + will be changed to +
    field   [0] INTEGER(1..8) --comment
    +
  6. +
+

diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngineTest.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngineTest.java new file mode 100644 index 0000000000..d491765c54 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/AsnPreprocessorEngineTest.java @@ -0,0 +1,167 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess; + +import org.apache.nifi.logging.ComponentLog; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.StringJoiner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class AsnPreprocessorEngineTest { + private AsnPreprocessorEngine testSubject; + private AsnPreprocessorEngine helper; + + private AsnPreprocessor mockPreprocessor1; + private AsnPreprocessor mockPreprocessor2; + private List preprocessors; + + private ComponentLog log; + + @TempDir + private File additionalPreprocessingOutputDirectory; + + @BeforeEach + void setUp() throws Exception { + mockPreprocessor1 = mock(AsnPreprocessor.class); + mockPreprocessor2 = mock(AsnPreprocessor.class); + + preprocessors = Arrays.asList( + mockPreprocessor1, + mockPreprocessor2 + ); + + log = mock(ComponentLog.class); + + helper = mock(AsnPreprocessorEngine.class); + testSubject = new AsnPreprocessorEngine() { + @Override + List readAsnLines(ComponentLog componentLog, String inputFile, Path inputFilePath) { + return helper.readAsnLines(componentLog, inputFile, inputFilePath); + } + + @Override + void writePreprocessedAsn(ComponentLog componentLog, String preprocessedAsn, Path preprocessedAsnPath) { + helper.writePreprocessedAsn(componentLog, preprocessedAsn, preprocessedAsnPath); + } + + @Override + List getPreprocessors() { + return preprocessors; + } + }; + } + + @Test + void testPreprocess() { + // GIVEN + Path asnFile1Path = Paths.get("path", "to", "asn_file_1"); + Path asnFile2Path = Paths.get("path", "to", "asn_file_2"); + + String asnFilesString = new StringJoiner(",") + .add(asnFile1Path.toString()) + .add(asnFile2Path.toString()) + .toString(); + + String outputDirectory = Paths.get("path", "to", "directory_for_transformed_asn_files").toString(); + + List originalLines1 = Arrays.asList("original_lines_1_1", "original_lines_1_2"); + List preprocessedLines1_1 = Arrays.asList("preprocessed_lines_1_1_1", "preprocessed_lines_1_1_2"); + List preprocessedLines1_2 = Arrays.asList("final_lines_1_1", "final_lines_1_2"); + + List originalLines2 = Arrays.asList("original_lines_2_1", "original_lines_2_2"); + List preprocessedLines2_1 = Arrays.asList("preprocessed_lines_2_1_1", "preprocessed_lines_2_1_2"); + List preprocessedLines2_2 = Arrays.asList("final_lines_2_1", "final_lines_2_2"); + + when(helper.readAsnLines(eq(log), eq(asnFile1Path.toString()), eq(asnFile1Path))) + .thenReturn(originalLines1); + when(mockPreprocessor1.preprocessAsn(originalLines1)).thenReturn(preprocessedLines1_1); + when(mockPreprocessor2.preprocessAsn(preprocessedLines1_1)).thenReturn(preprocessedLines1_2); + + when(helper.readAsnLines(eq(log), eq(asnFile2Path.toString()), eq(asnFile2Path))) + .thenReturn(originalLines2); + when(mockPreprocessor1.preprocessAsn(originalLines2)).thenReturn(preprocessedLines2_1); + when(mockPreprocessor2.preprocessAsn(preprocessedLines2_1)).thenReturn(preprocessedLines2_2); + + String expected = new StringJoiner(",") + .add(Paths.get("path", "to", "directory_for_transformed_asn_files", "asn_file_1").toString()) + .add(Paths.get("path", "to", "directory_for_transformed_asn_files", "asn_file_2").toString()) + .toString(); + + // WHEN + String actual = testSubject.preprocess(log, asnFilesString, outputDirectory); + + // THEN + assertEquals(expected, actual); + + verify(helper).readAsnLines(eq(log), eq(asnFile1Path.toString()), eq(asnFile1Path)); + verify(helper).readAsnLines(eq(log), eq(asnFile2Path.toString()), eq(asnFile2Path)); + + verify(mockPreprocessor1).preprocessAsn(originalLines1); + verify(mockPreprocessor2).preprocessAsn(preprocessedLines1_1); + + verify(mockPreprocessor1).preprocessAsn(originalLines2); + verify(mockPreprocessor2).preprocessAsn(preprocessedLines2_1); + + verify(helper).writePreprocessedAsn( + eq(log), + eq("final_lines_1_1" + System.lineSeparator() + "final_lines_1_2"), + eq(Paths.get("path", "to", "directory_for_transformed_asn_files", "asn_file_1")) + ); + + verify(helper).writePreprocessedAsn( + eq(log), + eq("final_lines_2_1" + System.lineSeparator() + "final_lines_2_2"), + eq(Paths.get("path", "to", "directory_for_transformed_asn_files", "asn_file_2")) + ); + } + + @Test + void testComplexPreprocessing() throws Exception { + testSubject = new AsnPreprocessorEngine(); + + String input = "test_complex_for_preprocessing.asn"; + + + String preprocessedFile = testSubject.preprocess( + log, + new File(getClass().getClassLoader().getResource(input).toURI()).getAbsolutePath(), + additionalPreprocessingOutputDirectory.getAbsolutePath() + ); + + String expected = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("preprocessed_" + input).toURI())), StandardCharsets.UTF_8) + .replace("\n", System.lineSeparator()); + + String actual = new String(Files.readAllBytes(Paths.get(preprocessedFile)), StandardCharsets.UTF_8); + + assertEquals(expected, actual); + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/AbstractAsnPreprocessorTest.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/AbstractAsnPreprocessorTest.java new file mode 100644 index 0000000000..9bb9c3c605 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/AbstractAsnPreprocessorTest.java @@ -0,0 +1,49 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.apache.nifi.jasn1.preprocess.AsnPreprocessor; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public abstract class AbstractAsnPreprocessorTest { + protected AsnPreprocessor testSubject; + + protected void testPreprocess(String input) throws IOException, URISyntaxException { + // GIVEN + List lines = Files.readAllLines(Paths.get(getClass().getClassLoader().getResource(input).toURI())); + + // WHEN + String actual = testSubject.preprocessAsn(lines) + .stream() + .collect(Collectors.joining(System.lineSeparator())); + + // THEN + String expected = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("preprocessed_" + input).toURI())), StandardCharsets.UTF_8) + .replace("\n", System.lineSeparator()); + + assertEquals(expected, actual); + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessorTest.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessorTest.java new file mode 100644 index 0000000000..7480210d57 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/ConstraintAsnPreprocessorTest.java @@ -0,0 +1,32 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ConstraintAsnPreprocessorTest extends AbstractAsnPreprocessorTest { + @BeforeEach + void setUp() { + testSubject = new ConstraintAsnPreprocessor(); + } + + @Test + void testPreprocessConstraints() throws Exception { + testPreprocess("test_constraints.asn"); + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessorTest.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessorTest.java new file mode 100644 index 0000000000..40d5850a5f --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/HuggingCommentAsnPreprocessorTest.java @@ -0,0 +1,32 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class HuggingCommentAsnPreprocessorTest extends AbstractAsnPreprocessorTest { + @BeforeEach + void setUp() { + testSubject = new HuggingCommentAsnPreprocessor(); + } + + @Test + void testPreprocessHuggingComment() throws Exception { + testPreprocess("test_hugging_comment.asn"); + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessorTest.java b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessorTest.java new file mode 100644 index 0000000000..8ff05f2067 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/java/org/apache/nifi/jasn1/preprocess/preprocessors/VersionBracketAsnPreprocessorTest.java @@ -0,0 +1,32 @@ +/* + * 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. + */ +package org.apache.nifi.jasn1.preprocess.preprocessors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class VersionBracketAsnPreprocessorTest extends AbstractAsnPreprocessorTest { + @BeforeEach + void setUp() { + testSubject = new VersionBracketAsnPreprocessor(); + } + + @Test + void testPreprocessVersionBracket() throws Exception { + testPreprocess("test_version_bracket.asn"); + } +} diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_complex_for_preprocessing.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_complex_for_preprocessing.asn new file mode 100644 index 0000000000..98222c7c98 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_complex_for_preprocessing.asn @@ -0,0 +1,15 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyType ::= SEQUENCE { + field1 [0] INTEGER , --Comment + -- comment2 + field2 INTEGER OPTIONAL, + field3 INTEGER OPTIONAL, + field4 INTEGER OPTIONAL +} + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_constraints.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_constraints.asn new file mode 100644 index 0000000000..3620a4269d --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_constraints.asn @@ -0,0 +1,27 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyTypeWithFieldConstraints := SEQUENCE { + field1 [0] INTEGER , + field2 [1] INTEGER , + field3 [2] INTEGER , + field4 [3] INTEGER OPTIONAL +} + +MyTypeWithSequenceSizeConstraint ::= SEQUENCE SIZE OF MyType + + + +MyTypeWithComponents ::= + MyType + + + + + + + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_hugging_comment.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_hugging_comment.asn new file mode 100644 index 0000000000..648d9bfcc2 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_hugging_comment.asn @@ -0,0 +1,12 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyTypeWithHuggingComment := SEQUENCE { + field [0] INTEGER(1..8) --comment +} + + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_version_bracket.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_version_bracket.asn new file mode 100644 index 0000000000..7b2a4b0af5 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/preprocessed_test_version_bracket.asn @@ -0,0 +1,44 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +VersionBracket1LineSingleField ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., + integerField3 INTEGER OPTIONAL +} + +VersionBracketCommentMultiLine ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., -- comment1 + -- comment2 + integerField3 INTEGER OPTIONAL, + integerField4 INTEGER OPTIONAL, + integerField5 INTEGER OPTIONAL +} + +VersionBracketMultiLineFirstHasField ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., -- comment1 + integerField3 INTEGER OPTIONAL, + integerField4 INTEGER OPTIONAL, + integerField5 INTEGER OPTIONAL +} + +TypeWithVersionBracketMultiLineBracketsAlone ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., + + integerField3 INTEGER OPTIONAL, + integerField4 INTEGER OPTIONAL, + integerField5 INTEGER OPTIONAL + +} + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_complex_for_preprocessing.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_complex_for_preprocessing.asn new file mode 100644 index 0000000000..5fcbf2d8fa --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_complex_for_preprocessing.asn @@ -0,0 +1,15 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyType ::= SEQUENCE { + field1 [0] INTEGER(1..8),--Comment +[[ -- comment2 + field2 INTEGER, + field3 INTEGER, + field4 INTEGER ]] +} + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_constraints.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_constraints.asn new file mode 100644 index 0000000000..bcf696dc4a --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_constraints.asn @@ -0,0 +1,27 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyTypeWithFieldConstraints := SEQUENCE { + field1 [0] INTEGER(1..8), + field2 [1] INTEGER(1..8,...), + field3 [2] INTEGER(1..8|100-200), + field4 [3] INTEGER(SIZE(1..8,...,10|12|20)) OPTIONAL +} + +MyTypeWithSequenceSizeConstraint ::= SEQUENCE SIZE(1..8) OF MyType + + + +MyTypeWithComponents ::= + MyType + (WITH COMPONENTS { + ..., + + -- some comment + field1 ABSENT + }|WITH COMPONENTS {..., field2 PRESENT}) + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_hugging_comment.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_hugging_comment.asn new file mode 100644 index 0000000000..7d7194c508 --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_hugging_comment.asn @@ -0,0 +1,12 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +MyTypeWithHuggingComment := SEQUENCE { + field [0] INTEGER(1..8)--comment +} + + +END \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_version_bracket.asn b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_version_bracket.asn new file mode 100644 index 0000000000..d21507716d --- /dev/null +++ b/nifi-nar-bundles/nifi-asn1-bundle/nifi-asn1-services/src/test/resources/test_version_bracket.asn @@ -0,0 +1,44 @@ +ORG-APACHE-NIFI-JASN1-TEST + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +VersionBracket1LineSingleField ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., +[[ integerField3 INTEGER ]] +} + +VersionBracketCommentMultiLine ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., -- comment1 +[[ -- comment2 + integerField3 INTEGER, + integerField4 INTEGER, + integerField5 INTEGER ]] +} + +VersionBracketMultiLineFirstHasField ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., -- comment1 +[[ integerField3 INTEGER, + integerField4 INTEGER, + integerField5 INTEGER ]] +} + +TypeWithVersionBracketMultiLineBracketsAlone ::= SEQUENCE { + integerField1 INTEGER, + integerField2 INTEGER, + ..., +[[ + integerField3 INTEGER, + integerField4 INTEGER, + integerField5 INTEGER +]] +} + +END \ No newline at end of file