From e812c4fa9d755f0364304df864bba9fec0f79a12 Mon Sep 17 00:00:00 2001 From: priyanshu Date: Mon, 5 Mar 2018 15:00:10 +0530 Subject: [PATCH] SDC-TOSCA Parser Integration SDC Onboarding Tosca Library to call SDC-Tosca Parser Change-Id: I12c92def4ff8e17431d73b0d39f62d5d79ea6f21 Issue-ID: SDC-1043 Signed-off-by: priyanshu --- .../openecomp/core/utilities/file/FileUtils.java | 49 ++++++- .../core/utilities/file/FileUtilsTest.java | 55 +++++++ .../utilities/file/resource-Spgw-csar-ZTE.csar | Bin 0 -> 31639 bytes openecomp-be/lib/openecomp-tosca-lib/pom.xml | 10 ++ .../sdc/tosca/services/ToscaValidationService.java | 31 ++++ .../services/impl/ToscaValidationServiceImpl.java | 159 +++++++++++++++++++++ .../config/SDCParser_error-configuration.yaml | 22 +++ ...rser_jtosca-validation-issue-configuration.yaml | 49 +++++++ .../impl/ToscaValidationServiceImplTest.java | 46 ++++++ .../csar/resource-Spgw-csar-ZTE.csar | Bin 0 -> 31639 bytes pom.xml | 2 +- 11 files changed, 421 insertions(+), 2 deletions(-) create mode 100644 openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/resources/org/openecomp/core/utilities/file/resource-Spgw-csar-ZTE.csar create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaValidationService.java create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImpl.java create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_error-configuration.yaml create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_jtosca-validation-issue-configuration.yaml create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImplTest.java create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/validationService/csar/resource-Spgw-csar-ZTE.csar diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java index e70ad923a2..f510febbcf 100644 --- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2017 European Support Limited + * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,20 @@ import org.openecomp.core.utilities.json.JsonUtil; import org.openecomp.sdc.tosca.services.YamlUtil; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.zip.ZipEntry; @@ -277,4 +284,44 @@ public class FileUtils { } + /** + * Write files and folders map to disk in the given path + * + * @param fileContentHandler the file content handler + * @param dir the dir + * @return a map containing file names and their absolute paths + * @throws IOException the io exception + */ + public static Map writeFilesFromFileContentHandler(FileContentHandler + fileContentHandler, + Path dir) + throws IOException { + + File file; + File dirFile = dir.toFile(); + Map filePaths = new HashMap<>(); + for (Map.Entry fileEntry : fileContentHandler.getFiles().entrySet()) { + file = new File(dirFile, fileEntry.getKey()); + file.getParentFile().mkdirs(); + filePaths.put(fileEntry.getKey(), file.getAbsolutePath()); + try (FileOutputStream fop = new FileOutputStream(file.getAbsolutePath());) { + fop.write(fileEntry.getValue()); + fop.flush(); + } + } + + return filePaths; + } + + /** + * Verify whether the provided extension is valid Yaml/Yml extension or not. + * + * @param fileExtension the file extension + * @return the boolean + */ + public static boolean isValidYamlExtension(String fileExtension){ + return fileExtension.equalsIgnoreCase(FileExtension.YML.getDisplayName()) || + fileExtension.equalsIgnoreCase(FileExtension.YAML.getDisplayName()); + } + } diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java index e32aa39904..3c00d40a6b 100644 --- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java @@ -1,12 +1,36 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed 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.openecomp.core.utilities.file; +import org.apache.commons.io.IOUtils; +import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum; import org.testng.annotations.Test; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; import java.util.function.Function; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertEquals; /** * @author EVITALIY @@ -45,4 +69,35 @@ public class FileUtilsTest { public void testReadViaInputStreamNotFound() throws Exception { FileUtils.readViaInputStream("notfound.txt", TEST_FUNCTION); } + + @Test + public void testWriteFilesFromFileContentHandler() throws IOException { + Path dir = Files.createTempDirectory("CSAR_" + System.currentTimeMillis()); + try { + byte[] uploadedFileData = IOUtils.toByteArray( + FileUtilsTest.class.getResource("resource-Spgw-csar-ZTE" + + ".csar")); + FileContentHandler contentMap = FileUtils.getFileContentMapFromZip(uploadedFileData); + Map filePaths = FileUtils.writeFilesFromFileContentHandler(contentMap, + dir); + + assertFalse(filePaths.isEmpty()); + assertEquals(filePaths.size(), 18); + for (Map.Entry fileEntry : filePaths.entrySet()) { + File f = new File(fileEntry.getValue()); + assertTrue(f.exists()); + } + } + finally { + org.apache.commons.io.FileUtils.deleteDirectory(dir.toFile()); + } + } + + @Test + public void testIsValidYamlExtension() throws IOException { + assertTrue(FileUtils.isValidYamlExtension("yaml")); + assertTrue(FileUtils.isValidYamlExtension("yml")); + assertFalse(FileUtils.isValidYamlExtension("yml1")); + assertFalse(FileUtils.isValidYamlExtension("zip")); + } } \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/resources/org/openecomp/core/utilities/file/resource-Spgw-csar-ZTE.csar b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/resources/org/openecomp/core/utilities/file/resource-Spgw-csar-ZTE.csar new file mode 100644 index 0000000000000000000000000000000000000000..58c3ddd074ff2eca5412dfb78912a5a575336d39 GIT binary patch literal 31639 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 G9sNJQ3f}(! literal 0 HcmV?d00001 diff --git a/openecomp-be/lib/openecomp-tosca-lib/pom.xml b/openecomp-be/lib/openecomp-tosca-lib/pom.xml index 14b4d7734c..8880c2bd07 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/pom.xml +++ b/openecomp-be/lib/openecomp-tosca-lib/pom.xml @@ -25,6 +25,11 @@ openecomp-utilities-lib ${project.version} + + org.openecomp.sdc + openecomp-sdc-validation-api + ${project.version} + org.openecomp.sdc openecomp-sdc-datatypes-lib @@ -69,6 +74,11 @@ openecomp-configuration-management-api ${openecomp.sdc.common.version} + + org.openecomp.sdc.sdc-tosca + sdc-tosca + ${sdc-tosca-parser.version} + diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaValidationService.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaValidationService.java new file mode 100644 index 0000000000..59d7acccd4 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaValidationService.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed 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.openecomp.sdc.tosca.services; + +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.datatypes.error.ErrorMessage; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public interface ToscaValidationService { + + public Map> validate(FileContentHandler fileContentHandler) + throws IOException; + +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImpl.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImpl.java new file mode 100644 index 0000000000..1c2c408c1a --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImpl.java @@ -0,0 +1,159 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed 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.openecomp.sdc.tosca.services.impl; + +import org.apache.commons.io.FilenameUtils; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.core.utilities.file.FileUtils; +import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum; +import org.openecomp.core.validation.ErrorMessageCode; +import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder; +import org.openecomp.sdc.datatypes.error.ErrorLevel; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.tosca.parser.config.ConfigurationManager; +import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException; +import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory; +import org.openecomp.sdc.tosca.services.ToscaValidationService; +import org.openecomp.sdc.toscaparser.api.common.JToscaValidationIssue; +import org.yaml.snakeyaml.Yaml; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ToscaValidationServiceImpl implements ToscaValidationService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ToscaValidationServiceImpl.class); + private static final String SDCPARSER_JTOSCA_VALIDATIONISSUE_CONFIG = + "SDCParser_jtosca-validation-issue-configuration.yaml"; + private static final String SDCPARSER_ERROR_CONFIG = "SDCParser_error-configuration.yaml"; + private static final String TOSCA_DEFINITION_VERSION = "tosca_definitions_version"; + + static { + // Override default SDC Parser configuration + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + configurationManager.setJtoscaValidationIssueConfiguration(SDCPARSER_JTOSCA_VALIDATIONISSUE_CONFIG); + configurationManager.setErrorConfiguration(SDCPARSER_ERROR_CONFIG); + SdcToscaParserFactory.setConfigurationManager(configurationManager); + } + + @Override + public Map> validate(FileContentHandler fileContentHandler) + throws IOException { + + Path dir = + Files.createTempDirectory(OnboardingTypesEnum.CSAR + "_" + System.currentTimeMillis()); + try { + // Write temporary files and folders to File System + Map filePaths = FileUtils.writeFilesFromFileContentHandler + (fileContentHandler, dir); + // Process Tosca Yaml validation + return processToscaYamls(filePaths); + } finally { + // Cleanup temporary files and folders from file system + org.apache.commons.io.FileUtils.deleteDirectory(dir.toFile()); + } + } + + private Map> processToscaYamls(Map filePaths) { + Map validFilePaths = getValidFilePaths(filePaths); + Map> validationIssues = new HashMap<>(); + + // Process Yaml Files + for (Map.Entry fileEntry : validFilePaths.entrySet()) { + try { + SdcToscaParserFactory factory = SdcToscaParserFactory.getInstance(); + factory.getSdcCsarHelper(fileEntry.getValue()); + processValidationIssues(fileEntry.getKey(), factory, validationIssues); + } catch (SdcToscaParserException stpe) { + LOGGER.error("SDC Parser Exception from SDC Parser Library : " + stpe); + ErrorMessage.ErrorMessageUtil.addMessage(fileEntry.getKey(), validationIssues).add( + new ErrorMessage(ErrorLevel.ERROR, ErrorMessagesFormatBuilder + .getErrorWithParameters(new ErrorMessageCode("JE000"), "Unexpected Error " + + "occurred"))); + } + catch (RuntimeException rte) { + LOGGER.error("Runtime Exception from SDC Parser Library : " + rte); + ErrorMessage.ErrorMessageUtil.addMessage(fileEntry.getKey(), validationIssues).add( + new ErrorMessage(ErrorLevel.ERROR, ErrorMessagesFormatBuilder + .getErrorWithParameters(new ErrorMessageCode("JE000"), "Unexpected Error " + + "occurred"))); + } + } + return validationIssues; + } + + private Map getValidFilePaths(Map filePaths) { + return filePaths.entrySet() + .stream() + .filter(map -> FileUtils.isValidYamlExtension(FilenameUtils.getExtension(map.getKey())) + && isToscaYaml(map.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + private boolean isToscaYaml(String filePath) { + boolean retValue = false; + + try (InputStream input = new BufferedInputStream(new FileInputStream(new File(filePath)));) { + Yaml yaml = new Yaml(); + LinkedHashMap data = (LinkedHashMap) yaml.load(input); + if(data.get(TOSCA_DEFINITION_VERSION) != null) { + retValue = true; + } + } + catch(Exception e){ + LOGGER.info("Ignore the exception as the input file may not be a Tosca Yaml; let the " + + "default value return", e); + } + return retValue; + } + + private void processValidationIssues(String fileName, SdcToscaParserFactory factory, Map> validationIssues) { + + List criticalsReport = factory.getCriticalExceptions(); + criticalsReport.stream().forEach(err -> + ErrorMessage.ErrorMessageUtil.addMessage(fileName, validationIssues).add( + new ErrorMessage(ErrorLevel.ERROR, ErrorMessagesFormatBuilder + .getErrorWithParameters(new ErrorMessageCode(err.getCode()), err.getMessage())))); + + List warningsReport = factory.getWarningExceptions(); + warningsReport.stream().forEach(err -> + ErrorMessage.ErrorMessageUtil.addMessage(fileName, validationIssues).add( + new ErrorMessage(ErrorLevel.WARNING, ErrorMessagesFormatBuilder + .getErrorWithParameters(new ErrorMessageCode(err.getCode()), err.getMessage())))); + + List notAnalyzedReport = factory.getNotAnalyzadExceptions(); + notAnalyzedReport.stream().forEach(err -> + ErrorMessage.ErrorMessageUtil.addMessage(fileName, validationIssues).add( + new ErrorMessage(ErrorLevel.WARNING, ErrorMessagesFormatBuilder + .getErrorWithParameters(new ErrorMessageCode(err.getCode()), err.getMessage())))); + + } + +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_error-configuration.yaml b/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_error-configuration.yaml new file mode 100644 index 0000000000..f5c20aa347 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_error-configuration.yaml @@ -0,0 +1,22 @@ +# Errors +errors: + FILE_NOT_FOUND: { + code: TP0001, + failOnError: true, + message: "Error: CSAR file not found." + } + BAD_FORMAT: { + code: TP0002, + failOnError: true, + message: "Error: CSAR file bad format. Check the log for details." + } + CONFORMANCE_LEVEL_ERROR: { + code: TP0003, + failOnError: false, + message: "Error: CSAR version is unsupported. Parser supports versions %s to %s." + } + GENERAL_ERROR: { + code: TP0004, + failOnError: true, + message: "Error: an unexpected internal error occured." + } \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_jtosca-validation-issue-configuration.yaml b/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_jtosca-validation-issue-configuration.yaml new file mode 100644 index 0000000000..f4bb949c80 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/resources/config/SDCParser_jtosca-validation-issue-configuration.yaml @@ -0,0 +1,49 @@ +# jTosca validation issues +#by error code, type the validation issue to be CRITICAL/WARNING +# since Conformance level considered to this type. for example: +#JE001: +# - issueType: WARNING +# sinceCsarConformanceLevel: 3.0 +# - issueType: WARNING +# sinceCsarConformanceLevel: 5.0 +validationIssues: + # TypeMismatchError + JE001: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + # MissingType + JE002: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #MissingRequiredFieldError + JE003: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #MissingRequiredFieldError2 + JE004: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #InvalidGroupTargetException + JE005: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #Schema definition of \"%s\" has \"status\" attribute with an invalid value + JE006: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #The unit \"%s\" is not valid + JE007: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #ValidationError + JE008: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #ValueError: Expected max 2 arguments for function \"get_input\" but received \"%s\"",args.size()) + JE009: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 + #MissingRequiredFieldError3 + JE010: + - issueType: WARNING + sinceCsarConformanceLevel: 3.0 \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImplTest.java b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImplTest.java new file mode 100644 index 0000000000..c9ceb363a4 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaValidationServiceImplTest.java @@ -0,0 +1,46 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed 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.openecomp.sdc.tosca.services.impl; + +import org.apache.commons.io.IOUtils; +import org.junit.Test; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum; +import org.openecomp.sdc.common.utils.CommonUtil; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.tosca.services.ToscaValidationService; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertFalse; + +public class ToscaValidationServiceImplTest { + + @Test + public void validateCSARContentErrorHandling() throws IOException { + String resName = "/mock/validationService/csar/resource-Spgw-csar-ZTE.csar"; + byte[] uploadedFileData = IOUtils.toByteArray(this.getClass().getResource(resName)); + FileContentHandler contentMap = + CommonUtil.validateAndUploadFileContent(OnboardingTypesEnum.CSAR, uploadedFileData); + ToscaValidationService handler = new ToscaValidationServiceImpl(); + Map> errors = handler.validate(contentMap); + assertFalse(errors.isEmpty()); + } + +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/validationService/csar/resource-Spgw-csar-ZTE.csar b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/validationService/csar/resource-Spgw-csar-ZTE.csar new file mode 100644 index 0000000000000000000000000000000000000000..58c3ddd074ff2eca5412dfb78912a5a575336d39 GIT binary patch literal 31639 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 G9sNJQ3f}(! literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 77b678d8bc..985d1e17d3 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 3.0.3 - 1.1.56-SNAPSHOT + 1.2.3-SNAPSHOT jacoco -- 2.16.6