This is an automated email from the ASF dual-hosted git repository. isapego pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push: new 07e8a6b384 IGNITE-19944 ODBC 3.0: Propagate SQL errors from engine to driver (#3022) 07e8a6b384 is described below commit 07e8a6b384cc3c563255128fb36528a80756ab89 Author: Dmitriy Zabotlin <arcoli...@users.noreply.github.com> AuthorDate: Wed Jan 10 17:42:01 2024 +0200 IGNITE-19944 ODBC 3.0: Propagate SQL errors from engine to driver (#3022) Co-authored-by: dzabotlin <dzabot...@gridgain.com> --- modules/api/build.gradle | 7 + .../java/org/apache/ignite/lang/ErrorGroups.java | 19 + .../build.gradle | 17 +- .../error/code/annotations/ErrorCodeGroup.java} | 31 +- .../code/generators/AbstractCodeGenerator.java} | 25 +- .../error/code/generators/CppGenerator.java | 128 +++++ .../error/code/generators/CsharpGenerator.java | 107 +++++ .../error/code/generators/GenericGenerator.java | 92 ++++ .../code/processor/ErrorCodeGroupDescriptor.java} | 40 +- .../code/processor/ErrorCodeGroupProcessor.java | 192 ++++++++ .../ErrorCodeGroupProcessorException.java} | 39 +- .../ignite/client/detail/cluster_connection.cpp | 2 +- modules/platforms/cpp/ignite/common/CMakeLists.txt | 1 + .../platforms/cpp/ignite/common/big_integer.cpp | 2 +- modules/platforms/cpp/ignite/common/error_codes.h | 198 ++++++++ modules/platforms/cpp/ignite/common/ignite_error.h | 32 +- .../platforms/cpp/ignite/common/ignite_result.h | 4 +- .../network/detail/linux/linux_async_client.cpp | 5 +- .../network/detail/linux/linux_async_client.h | 4 +- .../detail/linux/linux_async_client_pool.cpp | 8 +- .../detail/linux/linux_async_worker_thread.cpp | 6 +- .../network/detail/linux/tcp_socket_client.h | 6 +- .../platforms/cpp/ignite/network/detail/utils.h | 2 +- .../cpp/ignite/network/error_handling_filter.cpp | 4 +- modules/platforms/cpp/ignite/odbc/common_types.cpp | 180 +++++++ modules/platforms/cpp/ignite/odbc/common_types.h | 9 + .../cpp/ignite/odbc/diagnostic/diagnosable.h | 2 +- .../platforms/cpp/ignite/odbc/sql_connection.cpp | 2 +- .../platforms/cpp/ignite/odbc/sql_statement.cpp | 2 +- modules/platforms/cpp/ignite/protocol/utils.cpp | 4 +- .../platforms/cpp/tests/client-test/sql_test.cpp | 9 +- .../platforms/cpp/tests/odbc-test/error_test.cpp | 19 +- .../cpp/tests/odbc-test/transaction_test.cpp | 6 +- .../ErrorGroupsGenerator.cs | 148 ------ .../platforms/dotnet/Apache.Ignite/ErrorCodes.g.cs | 531 +++++++++++++++++++++ settings.gradle | 2 + 36 files changed, 1592 insertions(+), 293 deletions(-) diff --git a/modules/api/build.gradle b/modules/api/build.gradle index bb3ff39da3..63face865d 100644 --- a/modules/api/build.gradle +++ b/modules/api/build.gradle @@ -22,6 +22,9 @@ apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" dependencies { + annotationProcessor project(':ignite-error-code-annotation-processor') + + implementation project(':ignite-error-code-annotation-processor') implementation libs.fastutil.core implementation libs.jetbrains.annotations @@ -34,4 +37,8 @@ dependencies { testFixturesImplementation libs.jetbrains.annotations } +compileJava { + options.headerOutputDirectory = file("${projectDir}/../platforms/") +} + description = 'ignite-api' diff --git a/modules/api/src/main/java/org/apache/ignite/lang/ErrorGroups.java b/modules/api/src/main/java/org/apache/ignite/lang/ErrorGroups.java index 108ccb25b1..a9a1e36e4a 100755 --- a/modules/api/src/main/java/org/apache/ignite/lang/ErrorGroups.java +++ b/modules/api/src/main/java/org/apache/ignite/lang/ErrorGroups.java @@ -20,6 +20,7 @@ package org.apache.ignite.lang; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import java.util.Locale; +import org.apache.ignite.error.code.annotations.ErrorCodeGroup; /** * Defines error groups and its errors. @@ -112,6 +113,7 @@ public class ErrorGroups { } /** Common error group. */ + @ErrorCodeGroup public static class Common { /** Common error group. */ public static final ErrorGroup COMMON_ERR_GROUP = registerGroup("CMN", (short) 1); @@ -139,6 +141,7 @@ public class ErrorGroups { } /** Tables error group. */ + @ErrorCodeGroup public static class Table { /** Table error group. */ public static final ErrorGroup TABLE_ERR_GROUP = registerGroup("TBL", (short) 2); @@ -166,6 +169,7 @@ public class ErrorGroups { } /** Client error group. */ + @ErrorCodeGroup public static class Client { /** Client error group. */ public static final ErrorGroup CLIENT_ERR_GROUP = registerGroup("CLIENT", (short) 3); @@ -202,6 +206,7 @@ public class ErrorGroups { } /** SQL error group. */ + @ErrorCodeGroup public static class Sql { /** SQL error group. */ public static final ErrorGroup SQL_ERR_GROUP = registerGroup("SQL", (short) 4); @@ -272,6 +277,7 @@ public class ErrorGroups { } /** Meta storage error group. */ + @ErrorCodeGroup public static class MetaStorage { /** Meta storage error group. */ public static final ErrorGroup META_STORAGE_ERR_GROUP = registerGroup("META", (short) 5); @@ -293,6 +299,7 @@ public class ErrorGroups { } /** Index error group. */ + @ErrorCodeGroup public static class Index { /** Index error group. */ public static final ErrorGroup INDEX_ERR_GROUP = registerGroup("IDX", (short) 6); @@ -308,6 +315,7 @@ public class ErrorGroups { } /** Transactions error group. */ + @ErrorCodeGroup public static class Transactions { /** Transactions error group. */ public static final ErrorGroup TX_ERR_GROUP = registerGroup("TX", (short) 7); @@ -353,6 +361,7 @@ public class ErrorGroups { } /** Replicator error group. */ + @ErrorCodeGroup public static class Replicator { /** Replicator error group. */ public static final ErrorGroup REPLICATOR_ERR_GROUP = registerGroup("REP", (short) 8); @@ -386,6 +395,7 @@ public class ErrorGroups { } /** Storage error group. */ + @ErrorCodeGroup public static class Storage { /** Storage error group. */ public static final ErrorGroup STORAGE_ERR_GROUP = registerGroup("STORAGE", (short) 9); @@ -404,6 +414,7 @@ public class ErrorGroups { } /** Distribution zones error group. */ + @ErrorCodeGroup public static class DistributionZones { /** Distribution zones group. */ public static final ErrorGroup DISTRIBUTION_ZONES_ERR_GROUP = registerGroup("DISTRZONES", (short) 10); @@ -425,6 +436,7 @@ public class ErrorGroups { } /** Network error group. */ + @ErrorCodeGroup public static class Network { /** Network error group. */ public static final ErrorGroup NETWORK_ERR_GROUP = registerGroup("NETWORK", (short) 11); @@ -440,6 +452,7 @@ public class ErrorGroups { } /** Node configuration error group. */ + @ErrorCodeGroup public static class NodeConfiguration { /** Node configuration error group. */ public static final ErrorGroup NODE_CONFIGURATION_ERR_GROUP = registerGroup("NODECFG", (short) 12); @@ -458,6 +471,7 @@ public class ErrorGroups { } /** Code deployment error group. */ + @ErrorCodeGroup public static class CodeDeployment { /** Code deployment error group. */ public static final ErrorGroup CODE_DEPLOYMENT_ERR_GROUP = registerGroup("CODEDEPLOY", (short) 13); @@ -478,6 +492,7 @@ public class ErrorGroups { /** * Garbage collector error group. */ + @ErrorCodeGroup public static class GarbageCollector { /** Garbage collector error group. */ public static final ErrorGroup GC_ERR_GROUP = registerGroup("GC", (short) 14); @@ -489,6 +504,7 @@ public class ErrorGroups { /** * Authentication error group. */ + @ErrorCodeGroup public static class Authentication { /** Authentication error group. */ public static final ErrorGroup AUTHENTICATION_ERR_GROUP = registerGroup("AUTHENTICATION", (short) 15); @@ -506,6 +522,7 @@ public class ErrorGroups { /** * Compute error group. */ + @ErrorCodeGroup public static class Compute { /** Compute error group. */ public static final ErrorGroup COMPUTE_ERR_GROUP = registerGroup("COMPUTE", (short) 16); @@ -539,6 +556,7 @@ public class ErrorGroups { } /** Catalog error group. */ + @ErrorCodeGroup public static class Catalog { /** Catalog error group. */ public static final ErrorGroup CATALOG_ERR_GROUP = registerGroup("CATALOG", (short) 17); @@ -548,6 +566,7 @@ public class ErrorGroups { } /** Placement driver error group. */ + @ErrorCodeGroup public static class PlacementDriver { /** Placement driver error group. */ public static final ErrorGroup PLACEMENT_DRIVER_ERR_GROUP = registerGroup("PLACEMENTDRIVER", (short) 18); diff --git a/modules/api/build.gradle b/modules/error-code-annotation-processor/build.gradle similarity index 74% copy from modules/api/build.gradle copy to modules/error-code-annotation-processor/build.gradle index bb3ff39da3..b360c63da5 100644 --- a/modules/api/build.gradle +++ b/modules/error-code-annotation-processor/build.gradle @@ -18,20 +18,15 @@ apply from: "$rootDir/buildscripts/java-core.gradle" apply from: "$rootDir/buildscripts/publishing.gradle" apply from: "$rootDir/buildscripts/java-junit5.gradle" -apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" - dependencies { - implementation libs.fastutil.core implementation libs.jetbrains.annotations + implementation libs.fastutil.core + implementation libs.javapoet + implementation libs.auto.service.annotations + implementation libs.guava - testImplementation libs.hamcrest.core - testImplementation libs.hamcrest.optional - testImplementation libs.archunit.core - testImplementation libs.archunit.junit5 - - testFixturesImplementation libs.hamcrest.core - testFixturesImplementation libs.jetbrains.annotations + annotationProcessor libs.auto.service } -description = 'ignite-api' +description = 'ignite-error-code-annotation-processor' diff --git a/modules/api/build.gradle b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/error/code/annotations/ErrorCodeGroup.java similarity index 55% copy from modules/api/build.gradle copy to modules/error-code-annotation-processor/src/main/java/org/apache/ignite/error/code/annotations/ErrorCodeGroup.java index bb3ff39da3..e850d70e7a 100644 --- a/modules/api/build.gradle +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/error/code/annotations/ErrorCodeGroup.java @@ -15,23 +15,20 @@ * limitations under the License. */ -apply from: "$rootDir/buildscripts/java-core.gradle" -apply from: "$rootDir/buildscripts/publishing.gradle" -apply from: "$rootDir/buildscripts/java-junit5.gradle" -apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" +package org.apache.ignite.error.code.annotations; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; -dependencies { - implementation libs.fastutil.core - implementation libs.jetbrains.annotations - - testImplementation libs.hamcrest.core - testImplementation libs.hamcrest.optional - testImplementation libs.archunit.core - testImplementation libs.archunit.junit5 - - testFixturesImplementation libs.hamcrest.core - testFixturesImplementation libs.jetbrains.annotations +/** + * <p> + * Annotation that should be placed on the ErrorGroup in the java/org/apache/ignite/lang/ErrorGroups.java + * </p> + * <p> + * Group will be processed by the @{@link org.apache.ignite.internal.error.code.processor.ErrorCodeGroupProcessor} + * and C++ and C# files with errors will be generated. + * </p> + */ +@Target(ElementType.TYPE) +public @interface ErrorCodeGroup { } - -description = 'ignite-api' diff --git a/modules/api/build.gradle b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/AbstractCodeGenerator.java similarity index 55% copy from modules/api/build.gradle copy to modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/AbstractCodeGenerator.java index bb3ff39da3..d029eb4ac3 100644 --- a/modules/api/build.gradle +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/AbstractCodeGenerator.java @@ -15,23 +15,14 @@ * limitations under the License. */ -apply from: "$rootDir/buildscripts/java-core.gradle" -apply from: "$rootDir/buildscripts/publishing.gradle" -apply from: "$rootDir/buildscripts/java-junit5.gradle" -apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" +package org.apache.ignite.internal.error.code.generators; +import java.util.List; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupDescriptor; -dependencies { - implementation libs.fastutil.core - implementation libs.jetbrains.annotations - - testImplementation libs.hamcrest.core - testImplementation libs.hamcrest.optional - testImplementation libs.archunit.core - testImplementation libs.archunit.junit5 - - testFixturesImplementation libs.hamcrest.core - testFixturesImplementation libs.jetbrains.annotations +/** + * Abstract error code generator. + */ +public interface AbstractCodeGenerator { + void generate(List<ErrorCodeGroupDescriptor> descriptors); } - -description = 'ignite-api' diff --git a/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CppGenerator.java b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CppGenerator.java new file mode 100644 index 0000000000..5dc10a64ca --- /dev/null +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CppGenerator.java @@ -0,0 +1,128 @@ +/* + * 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.ignite.internal.error.code.generators; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.processing.ProcessingEnvironment; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupDescriptor; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupProcessorException; + +/** + * C++ generator for Error Codes. + */ +public class CppGenerator extends GenericGenerator { + private static final String SuffixToChop = "_ERR"; + + public CppGenerator(ProcessingEnvironment processingEnvironment, Path outFilePath) { + super(processingEnvironment, outFilePath); + } + + private void generateHeader() throws IOException { + line("// THIS IS AUTO-GENERATED FILE. DO NOT EDIT."); + line(); + line("#pragma once"); + line(); + line("#include <cstdint>"); + line(); + } + + private void generateEnum(String comment, String name, List<String> valueNames, List<Integer> values) throws IOException { + if (valueNames.size() != values.size()) { + throw new ErrorCodeGroupProcessorException("valueNames.size() != values.size()"); + } + + line(comment); + line("enum class " + name + " : underlying_t {"); + for (int i = 0; i < valueNames.size(); i++) { + var last = i == valueNames.size() - 1; + line(String.format(" %s = 0x%s%s", valueNames.get(i), Integer.toHexString(values.get(i)), last ? "" : ",")); + } + line("};"); + line(); + } + + private void generateErrorCodeGroup(ErrorCodeGroupDescriptor descriptor, boolean lastGroup) throws IOException { + var groupCode = descriptor.groupCode; + line(" // " + descriptor.className + " group. Group code: " + descriptor.groupCode); + + for (int i = 0; i < descriptor.errorCodes.size(); i++) { + var lastInGroup = i == descriptor.errorCodes.size() - 1; + var ec = descriptor.errorCodes.get(i); + var name = composeName(ec.name); + var code = Integer.toHexString(composeCode(groupCode, ec.code)); + line(String.format(" %s = 0x%s%s", name, code, lastGroup && lastInGroup ? "" : ",")); + if (lastInGroup && !lastGroup) { + line(); + } + } + } + + private void generateErrorCodeEnumStart() throws IOException { + line("// Error codes."); + line("enum class code : underlying_t {"); + } + + private void generateErrorCodeEnumEnd() throws IOException { + line("};"); + line(); + } + + @Override + void generateFile(List<ErrorCodeGroupDescriptor> descriptors) throws IOException { + generateHeader(); + line("namespace ignite {"); + line(); + line("namespace error {"); + line(); + line("using underlying_t = std::uint32_t;"); + line(); + line("static inline const std::uint32_t group_shift = " + groupShift + ";"); + line(); + generateEnum("// Error groups codes.", + "group", + descriptors.stream().map(d -> d.groupName).collect(Collectors.toList()), + descriptors.stream().map(d -> d.groupCode).collect(Collectors.toList())); + line("inline group get_group_by_error_code(const underlying_t code) {"); + line(" return group(code >> group_shift);"); + line("}"); + line(); + generateErrorCodeEnumStart(); + for (int i = 0; i < descriptors.size(); i++) { + generateErrorCodeGroup(descriptors.get(i), i == descriptors.size() - 1); + } + generateErrorCodeEnumEnd(); + line("} // namespace error"); + line(); + line("} // namespace ignite"); + } + + private static int composeCode(int groupCode, int errorCode) { + return groupCode << groupShift | errorCode; + } + + private static String composeName(String name) { + if (name.endsWith(SuffixToChop)) { + return name.substring(0, name.length() - SuffixToChop.length()); + } + + return name; + } +} diff --git a/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CsharpGenerator.java b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CsharpGenerator.java new file mode 100644 index 0000000000..c378ec06df --- /dev/null +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/CsharpGenerator.java @@ -0,0 +1,107 @@ +/* + * 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.ignite.internal.error.code.generators; + +import com.google.common.base.CaseFormat; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import javax.annotation.processing.ProcessingEnvironment; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupDescriptor; + +/** + * C# generator for Error Codes. + */ +public class CsharpGenerator extends GenericGenerator { + private static final String SuffixToChop = "Err"; + + public CsharpGenerator(ProcessingEnvironment processingEnvironment, Path outFilePath) { + super(processingEnvironment, outFilePath); + } + + private static String transfromErrorCodeName(String name) { + var transformed = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name); + if (transformed.endsWith(SuffixToChop)) { + return transformed.substring(0, transformed.length() - SuffixToChop.length()); + } + return transformed; + } + + @Override + void generateFile(List<ErrorCodeGroupDescriptor> descriptors) throws IOException { + line("// <auto-generated/>"); + line("namespace Apache.Ignite"); + line("{"); + line(" using System;"); + line(); + generateClass(descriptors); + line("}"); + } + + private void generateClass(List<ErrorCodeGroupDescriptor> descriptors) throws IOException { + line(" public static partial class ErrorGroups"); + line(" {"); + line(" /// <summary>"); + line(" /// Gets the group name by code."); + line(" /// </summary>"); + line(" /// <param name=\"groupCode\">Group code.</param>"); + line(" /// <returns>Group name.</returns>"); + line(" public static string GetGroupName(int groupCode) => groupCode switch"); + line(" {"); + for (var descriptor : descriptors) { + line(" " + descriptor.className + ".GroupCode => " + descriptor.className + ".GroupName,"); + } + line(); + line(" _ => UnknownGroupName"); + line(" };"); + for (var descriptor : descriptors) { + generateErrorGroupClass(descriptor); + } + line(" }"); + } + + private void generateErrorGroupClass(ErrorCodeGroupDescriptor descriptor) throws IOException { + line(); + line(" /// <summary> " + descriptor.className + " errors. </summary>"); + line(" public static class " + descriptor.className); + line(" {"); + + line(" /// <summary> " + descriptor.className + " group code. </summary>"); + line(" public const short GroupCode = " + descriptor.groupCode + ";"); + line(); + + line(" /// <summary> " + descriptor.className + " group name. </summary>"); + line(" public const String GroupName = \"" + descriptor.groupName + "\";"); + line(); + + for (int i = 0; i < descriptor.errorCodes.size(); i++) { + generateErrorCode(descriptor.errorCodes.get(i).name, descriptor.errorCodes.get(i).code); + if (i != descriptor.errorCodes.size() - 1) { + line(); + } + } + + line(" }"); + } + + private void generateErrorCode(String name, int code) throws IOException { + line(String.format(" /// <summary> %s error. </summary>", transfromErrorCodeName(name))); + line(String.format(" public const int %s = (GroupCode << %d) | (%d & 0xFFFF);", transfromErrorCodeName(name), groupShift, + code)); + } +} diff --git a/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/GenericGenerator.java b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/GenericGenerator.java new file mode 100644 index 0000000000..2a57f32808 --- /dev/null +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/generators/GenericGenerator.java @@ -0,0 +1,92 @@ +/* + * 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.ignite.internal.error.code.generators; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import javax.annotation.processing.ProcessingEnvironment; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupDescriptor; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupProcessorException; + +/** + * Generic base class for error codes generators. + */ +public abstract class GenericGenerator implements AbstractCodeGenerator { + final ProcessingEnvironment processingEnvironment; + final Path outFilePath; + BufferedWriter writer; + static final int groupShift = 16; + + protected void line(String str) throws IOException { + writer.write(str); + writer.newLine(); + } + + protected void line() throws IOException { + line(""); + } + + GenericGenerator(ProcessingEnvironment processingEnvironment, Path outFilePath) { + this.processingEnvironment = processingEnvironment; + this.outFilePath = outFilePath; + } + + void generateFile(List<ErrorCodeGroupDescriptor> descriptors) throws IOException, ErrorCodeGroupProcessorException { + throw new ErrorCodeGroupProcessorException("generateFile not implemented!"); + } + + void generateLicense() throws IOException { + line("/* "); + line(" * Licensed to the Apache Software Foundation (ASF) under one or more "); + line(" * contributor license agreements. See the NOTICE file distributed with "); + line(" * this work for additional information regarding copyright ownership. "); + line(" * The ASF licenses this file to You under the Apache License, Version 2.0 "); + line(" * (the \"License\"); you may not use this file except in compliance with "); + line(" * the License. You may obtain a copy of the License at "); + line(" * "); + line(" * http://www.apache.org/licenses/LICENSE-2.0 "); + line(" * "); + line(" * Unless required by applicable law or agreed to in writing, software "); + line(" * distributed under the License is distributed on an \"AS IS\" BASIS, "); + line(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. "); + line(" * See the License for the specific language governing permissions and "); + line(" * limitations under the License. "); + line(" */ "); + line(); + } + + @Override + public void generate(List<ErrorCodeGroupDescriptor> descriptors) { + try { + FileObject resource = processingEnvironment.getFiler().createResource(StandardLocation.NATIVE_HEADER_OUTPUT, + "", + outFilePath.toString()); + + writer = new BufferedWriter(resource.openWriter()); + generateLicense(); + generateFile(descriptors); + writer.flush(); + } catch (IOException e) { + throw new ErrorCodeGroupProcessorException("IO exception during annotation processing", e); + } + } +} diff --git a/modules/api/build.gradle b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupDescriptor.java similarity index 55% copy from modules/api/build.gradle copy to modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupDescriptor.java index bb3ff39da3..14d970c233 100644 --- a/modules/api/build.gradle +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupDescriptor.java @@ -15,23 +15,33 @@ * limitations under the License. */ -apply from: "$rootDir/buildscripts/java-core.gradle" -apply from: "$rootDir/buildscripts/publishing.gradle" -apply from: "$rootDir/buildscripts/java-junit5.gradle" -apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" +package org.apache.ignite.internal.error.code.processor; +import java.util.ArrayList; +import java.util.List; -dependencies { - implementation libs.fastutil.core - implementation libs.jetbrains.annotations +/** + * Class that holds info about one group of error codes. + */ +public class ErrorCodeGroupDescriptor { + public String className; - testImplementation libs.hamcrest.core - testImplementation libs.hamcrest.optional - testImplementation libs.archunit.core - testImplementation libs.archunit.junit5 + public String groupName; - testFixturesImplementation libs.hamcrest.core - testFixturesImplementation libs.jetbrains.annotations -} + public Integer groupCode; + + /** + * Class that holds info about one error code. + */ + public static class ErrorCode { + ErrorCode(int code, String name) { + this.code = code; + this.name = name; + } -description = 'ignite-api' + public int code; + public String name; + } + + public List<ErrorCode> errorCodes = new ArrayList<>(); +} diff --git a/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessor.java b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessor.java new file mode 100644 index 0000000000..867a578f7d --- /dev/null +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessor.java @@ -0,0 +1,192 @@ +/* + * 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.ignite.internal.error.code.processor; + +import static java.util.stream.Collectors.toSet; + +import com.google.auto.service.AutoService; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MethodInvocationTree; +import com.sun.source.tree.ParenthesizedTree; +import com.sun.source.tree.TypeCastTree; +import com.sun.source.tree.VariableTree; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.TypeElement; +import org.apache.ignite.error.code.annotations.ErrorCodeGroup; +import org.apache.ignite.internal.error.code.generators.AbstractCodeGenerator; +import org.apache.ignite.internal.error.code.generators.CppGenerator; +import org.apache.ignite.internal.error.code.generators.CsharpGenerator; +import org.apache.ignite.internal.error.code.processor.ErrorCodeGroupDescriptor.ErrorCode; + +/** + * Annotation processor that process @{@link ErrorCodeGroup} annotation. + * + * <p> + * Collects all error groups and generates C++ and C# files with corresponding error codes groups. + * </p> + */ +@AutoService(Processor.class) +public class ErrorCodeGroupProcessor extends AbstractProcessor { + private Trees trees; + + @Override + public void init(ProcessingEnvironment pe) { + super.init(pe); + this.trees = Trees.instance(pe); + } + + /** {@inheritDoc} */ + @Override + public Set<String> getSupportedAnnotationTypes() { + return Set.of(ErrorCodeGroup.class.getName()); + } + + /** {@inheritDoc} */ + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + /** {@inheritDoc} */ + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + Set<TypeElement> errorGroups = annotations.stream() + .map(roundEnv::getElementsAnnotatedWith) + .flatMap(Collection::stream) + .map(TypeElement.class::cast) + .collect(toSet()); + + if (errorGroups.isEmpty()) { + return true; + } + + List<ErrorCodeGroupDescriptor> descriptors = new ArrayList<>(); + + for (TypeElement clazz : errorGroups) { + ErrorCodeTreeScanner codeScanner = new ErrorCodeTreeScanner(); + codeScanner.scan(this.trees.getPath(clazz), this.trees); + var descriptor = codeScanner.getDescriptor(); + descriptor.className = clazz.getSimpleName().toString(); + descriptors.add(descriptor); + } + + generate(descriptors); + + return true; + } + + private void generate(List<ErrorCodeGroupDescriptor> groups) { + groups.sort(Comparator.comparing(g -> g.groupCode)); + for (var group : groups) { + group.errorCodes.sort(Comparator.comparing(d -> d.code)); + } + + List<AbstractCodeGenerator> generators = List.of( + new CppGenerator(processingEnv, Path.of("cpp/ignite/common/error_codes.h")), + new CsharpGenerator(processingEnv, Path.of("dotnet/Apache.Ignite/ErrorCodes.g.cs")) + ); + + for (var generator : generators) { + generator.generate(groups); + } + } + + static class ErrorCodeTreeScanner extends TreePathScanner<Object, Trees> { + ErrorCodeTreeScanner() { + this.descriptor = new ErrorCodeGroupDescriptor(); + } + + private final ErrorCodeGroupDescriptor descriptor; + + private ErrorCodeGroupProcessorException ex; + + ErrorCodeGroupDescriptor getDescriptor() { + if (ex != null) { + throw ex; + } + + return descriptor; + } + + private Object visitErrorCodeField(VariableTree variableTree, Trees trees) { + // example: initializer = COMMON_ERR_GROUP.registerErrorCode((short) 1). + var initializer = variableTree.getInitializer(); + var name = variableTree.getName().toString(); + try { + // example: args = {"(short) 1"} as List<ExpressionTree>. + var args = ((MethodInvocationTree) initializer).getArguments(); + // example: expr = "(short) 1" as TypeCastTree. + var expr = ((TypeCastTree) args.get(0)).getExpression(); + // example: if expr is "(short) (1)" we should remove parentheses + if (expr instanceof ParenthesizedTree) { + expr = ((ParenthesizedTree) expr).getExpression(); + } + // example: extract 1 from "(short) 1" expression. + this.descriptor.errorCodes.add(new ErrorCode((Integer) ((LiteralTree) expr).getValue(), name)); + } catch (Exception e) { + ex = new ErrorCodeGroupProcessorException("AST parsing error", e); + } + + return super.visitVariable(variableTree, trees); + } + + private Object visitErrorCodeGroupField(VariableTree variableTree, Trees trees) { + var initializer = variableTree.getInitializer(); + try { + var args = ((MethodInvocationTree) initializer).getArguments(); + var groupNameExpr = ((LiteralTree) args.get(0)); + var groupCodeExpr = ((TypeCastTree) args.get(1)).getExpression(); + if (groupCodeExpr instanceof ParenthesizedTree) { + groupCodeExpr = ((ParenthesizedTree) groupCodeExpr).getExpression(); + } + this.descriptor.groupName = (String) groupNameExpr.getValue(); + this.descriptor.groupCode = (Integer) ((LiteralTree) groupCodeExpr).getValue(); + } catch (Exception e) { + ex = new ErrorCodeGroupProcessorException("AST parsing error", e); + } + + return super.visitVariable(variableTree, trees); + } + + /** {@inheritDoc} */ + @Override + public Object visitVariable(VariableTree variableTree, Trees trees) { + if (variableTree.getType().toString().equals("int")) { + return visitErrorCodeField(variableTree, trees); + } + + if (variableTree.getType().toString().equals("ErrorGroup")) { + return visitErrorCodeGroupField(variableTree, trees); + } + + return super.visitVariable(variableTree, trees); + } + } +} diff --git a/modules/api/build.gradle b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessorException.java similarity index 55% copy from modules/api/build.gradle copy to modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessorException.java index bb3ff39da3..6a18b020e9 100644 --- a/modules/api/build.gradle +++ b/modules/error-code-annotation-processor/src/main/java/org/apache/ignite/internal/error/code/processor/ErrorCodeGroupProcessorException.java @@ -15,23 +15,30 @@ * limitations under the License. */ -apply from: "$rootDir/buildscripts/java-core.gradle" -apply from: "$rootDir/buildscripts/publishing.gradle" -apply from: "$rootDir/buildscripts/java-junit5.gradle" -apply from: "$rootDir/buildscripts/java-test-fixtures.gradle" +package org.apache.ignite.internal.error.code.processor; +import org.jetbrains.annotations.Nullable; -dependencies { - implementation libs.fastutil.core - implementation libs.jetbrains.annotations - - testImplementation libs.hamcrest.core - testImplementation libs.hamcrest.optional - testImplementation libs.archunit.core - testImplementation libs.archunit.junit5 +/** + * Exception that can be thrown from the @{@link ErrorCodeGroupProcessor}. + */ +public class ErrorCodeGroupProcessorException extends RuntimeException { + /** + * Constructor. + * + * @param message Error massage. + */ + public ErrorCodeGroupProcessorException(String message) { + super(message); + } - testFixturesImplementation libs.hamcrest.core - testFixturesImplementation libs.jetbrains.annotations + /** + * Constructor. + * + * @param message Error message. + * @param cause Cause + */ + public ErrorCodeGroupProcessorException(String message, @Nullable Throwable cause) { + super(message, cause); + } } - -description = 'ignite-api' diff --git a/modules/platforms/cpp/ignite/client/detail/cluster_connection.cpp b/modules/platforms/cpp/ignite/client/detail/cluster_connection.cpp index 9425a162d8..eab18a794a 100644 --- a/modules/platforms/cpp/ignite/client/detail/cluster_connection.cpp +++ b/modules/platforms/cpp/ignite/client/detail/cluster_connection.cpp @@ -104,7 +104,7 @@ void cluster_connection::on_connection_error(const end_point &addr, ignite_error m_logger->log_warning( "Failed to establish connection with remote host " + addr.to_string() + ", reason: " + err.what()); - if (err.get_status_code() == status_code::OS) + if (err.get_status_code() == error::code::INTERNAL || err.get_status_code() == error::code::GENERIC) initial_connect_result(std::move(err)); } diff --git a/modules/platforms/cpp/ignite/common/CMakeLists.txt b/modules/platforms/cpp/ignite/common/CMakeLists.txt index b1194954f8..60f97b07fd 100644 --- a/modules/platforms/cpp/ignite/common/CMakeLists.txt +++ b/modules/platforms/cpp/ignite/common/CMakeLists.txt @@ -28,6 +28,7 @@ set(PUBLIC_HEADERS bytes_view.h config.h end_point.h + error_codes.h ignite_date.h ignite_date_time.h ignite_duration.h diff --git a/modules/platforms/cpp/ignite/common/big_integer.cpp b/modules/platforms/cpp/ignite/common/big_integer.cpp index a6ebe00941..63d56ba425 100644 --- a/modules/platforms/cpp/ignite/common/big_integer.cpp +++ b/modules/platforms/cpp/ignite/common/big_integer.cpp @@ -614,7 +614,7 @@ uint32_t big_integer::get_mag_int(int32_t n) const { void big_integer::divide(const big_integer &divisor, big_integer &res, big_integer *rem) const { // Can't divide by zero. if (divisor.mag.empty()) - throw ignite_error(status_code::GENERIC, "Division by zero."); + throw ignite_error(error::code::GENERIC, "Division by zero."); int32_t compRes = compare(divisor, true); auto resSign = int8_t(sign * divisor.sign); diff --git a/modules/platforms/cpp/ignite/common/error_codes.h b/modules/platforms/cpp/ignite/common/error_codes.h new file mode 100644 index 0000000000..3122b0af8a --- /dev/null +++ b/modules/platforms/cpp/ignite/common/error_codes.h @@ -0,0 +1,198 @@ +/* + * 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. + */ + +// THIS IS AUTO-GENERATED FILE. DO NOT EDIT. + +#pragma once + +#include <cstdint> + +namespace ignite { + +namespace error { + +using underlying_t = std::uint32_t; + +static inline const std::uint32_t group_shift = 16; + +// Error groups codes. +enum class group : underlying_t { + CMN = 0x1, + TBL = 0x2, + CLIENT = 0x3, + SQL = 0x4, + META = 0x5, + IDX = 0x6, + TX = 0x7, + REP = 0x8, + STORAGE = 0x9, + DISTRZONES = 0xa, + NETWORK = 0xb, + NODECFG = 0xc, + CODEDEPLOY = 0xd, + GC = 0xe, + AUTHENTICATION = 0xf, + COMPUTE = 0x10, + CATALOG = 0x11, + PLACEMENTDRIVER = 0x12 +}; + +inline group get_group_by_error_code(const underlying_t code) { + return group(code >> group_shift); +} + +// Error codes. +enum class code : underlying_t { + // Common group. Group code: 1 + NODE_STOPPING = 0x10001, + COMPONENT_NOT_STARTED = 0x10002, + ILLEGAL_ARGUMENT = 0x10003, + SSL_CONFIGURATION = 0x10004, + NODE_LEFT = 0x10005, + INTERNAL = 0x1ffff, + + // Table group. Group code: 2 + TABLE_ALREADY_EXISTS = 0x20001, + TABLE_NOT_FOUND = 0x20002, + COLUMN_ALREADY_EXISTS = 0x20003, + COLUMN_NOT_FOUND = 0x20004, + TABLE_STOPPING = 0x20005, + TABLE_DEFINITION = 0x20006, + SCHEMA_VERSION_MISMATCH = 0x20007, + + // Client group. Group code: 3 + CONNECTION = 0x30001, + PROTOCOL = 0x30002, + PROTOCOL_COMPATIBILITY = 0x30003, + TABLE_ID_NOT_FOUND = 0x30004, + AUTHENTICATION = 0x30005, + AUTHORIZATION = 0x30006, + CONFIGURATION = 0x30007, + CLUSTER_ID_MISMATCH = 0x30008, + CLIENT_SSL_CONFIGURATION = 0x30009, + HANDSHAKE_HEADER = 0x3000a, + + // Sql group. Group code: 4 + CURSOR_NO_MORE_PAGES = 0x40001, + QUERY_NO_RESULT_SET = 0x40002, + SCHEMA_NOT_FOUND = 0x40003, + CURSOR_CLOSED = 0x40004, + STMT_PARSE = 0x40005, + STMT_VALIDATION = 0x40006, + CONSTRAINT_VIOLATION = 0x40007, + EXECUTION_CANCELLED = 0x40008, + RUNTIME = 0x40009, + PLANNING_TIMEOUT = 0x4000a, + SESSION_CLOSED = 0x4000b, + MAPPING = 0x4000c, + TX_CONTROL_INSIDE_EXTERNAL_TX = 0x4000d, + + // MetaStorage group. Group code: 5 + STARTING_STORAGE = 0x50001, + RESTORING_STORAGE = 0x50002, + COMPACTION = 0x50003, + OP_EXECUTION = 0x50004, + OP_EXECUTION_TIMEOUT = 0x50005, + + // Index group. Group code: 6 + INVALID_INDEX_DEFINITION = 0x60001, + INDEX_NOT_FOUND = 0x60002, + INDEX_ALREADY_EXISTS = 0x60003, + + // Transactions group. Group code: 7 + TX_STATE_STORAGE = 0x70001, + TX_STATE_STORAGE_STOPPED = 0x70002, + TX_UNEXPECTED_STATE = 0x70003, + ACQUIRE_LOCK = 0x70004, + ACQUIRE_LOCK_TIMEOUT = 0x70005, + TX_COMMIT = 0x70006, + TX_ROLLBACK = 0x70007, + TX_FAILED_READ_WRITE_OPERATION = 0x70008, + TX_REPLICA_UNAVAILABLE = 0x70009, + TX_STATE_STORAGE_REBALANCE = 0x7000a, + TX_READ_ONLY_TOO_OLD = 0x7000b, + TX_INCOMPATIBLE_SCHEMA = 0x7000c, + TX_PRIMARY_REPLICA_EXPIRED = 0x7000d, + + // Replicator group. Group code: 8 + REPLICA_COMMON = 0x80001, + REPLICA_IS_ALREADY_STARTED = 0x80002, + REPLICA_TIMEOUT = 0x80003, + REPLICA_UNSUPPORTED_REQUEST = 0x80004, + REPLICA_UNAVAILABLE = 0x80005, + REPLICA_MISS = 0x80006, + CURSOR_CLOSE = 0x80007, + REPLICA_STOPPING = 0x80008, + REPLICATION_SAFE_TIME_REORDERING = 0x80009, + + // Storage group. Group code: 9 + GENERIC = 0x90001, + DIRECTORY_CREATION = 0x90002, + ALREADY_CLOSED = 0x90003, + STORAGE_REBALANCE = 0x90004, + + // DistributionZones group. Group code: 10 + ZONE_ALREADY_EXISTS = 0xa0001, + ZONE_NOT_FOUND = 0xa0002, + ZONE_RENAME = 0xa0003, + ZONE_DROP = 0xa0004, + ZONE_DEFINITION = 0xa0005, + + // Network group. Group code: 11 + UNRESOLVABLE_CONSISTENT_ID = 0xb0001, + PORT_IN_USE = 0xb0002, + + // NodeConfiguration group. Group code: 12 + CONFIG_READ = 0xc0001, + CONFIG_FILE_CREATE = 0xc0002, + CONFIG_WRITE = 0xc0003, + CONFIG_PARSE = 0xc0004, + + // CodeDeployment group. Group code: 13 + UNIT_NOT_FOUND = 0xd0001, + UNIT_ALREADY_EXISTS = 0xd0002, + UNIT_CONTENT_READ = 0xd0003, + UNIT_UNAVAILABLE = 0xd0004, + + // GarbageCollector group. Group code: 14 + CLOSED = 0xe0001, + + // Authentication group. Group code: 15 + UNSUPPORTED_AUTHENTICATION_TYPE = 0xf0001, + INVALID_CREDENTIALS = 0xf0002, + BASIC_PROVIDER = 0xf0003, + + // Compute group. Group code: 16 + CLASS_PATH = 0x100001, + CLASS_LOADER = 0x100002, + CLASS_INITIALIZATION = 0x100003, + QUEUE_OVERFLOW = 0x100004, + COMPUTE_JOB_STATE_TRANSITION = 0x100005, + CANCELLING = 0x100006, + RESULT_NOT_FOUND = 0x100007, + + // Catalog group. Group code: 17 + VALIDATION = 0x110001, + + // PlacementDriver group. Group code: 18 + PRIMARY_REPLICA_AWAIT_TIMEOUT = 0x120001, + PRIMARY_REPLICA_AWAIT = 0x120002 +}; + +} // namespace error + +} // namespace ignite diff --git a/modules/platforms/cpp/ignite/common/ignite_error.h b/modules/platforms/cpp/ignite/common/ignite_error.h index 823d67dcb9..66b813f892 100644 --- a/modules/platforms/cpp/ignite/common/ignite_error.h +++ b/modules/platforms/cpp/ignite/common/ignite_error.h @@ -17,27 +17,14 @@ #pragma once +#include "error_codes.h" + #include <cstdint> #include <exception> #include <string> namespace ignite { -/** - * Status code. - */ -enum class status_code : std::int32_t { - SUCCESS = 0, - - GENERIC, - - UNKNOWN, - - NETWORK, - - OS, -}; - /** * Ignite Error. */ @@ -52,8 +39,7 @@ public: * @param message Message. */ explicit ignite_error(std::string message) noexcept - : m_status_code(status_code::GENERIC) - , m_message(std::move(message)) {} // NOLINT(bugprone-throw-keyword-missing) + : m_message(std::move(message)) {} // NOLINT(bugprone-throw-keyword-missing) /** * Constructor. @@ -61,8 +47,8 @@ public: * @param statusCode Status code. * @param message Message. */ - explicit ignite_error(status_code statusCode, std::string message) noexcept - : m_status_code(statusCode) + explicit ignite_error(error::code code, std::string message) noexcept + : m_status_code(code) , m_message(std::move(message)) {} // NOLINT(bugprone-throw-keyword-missing) /** @@ -72,8 +58,8 @@ public: * @param message Message. * @param cause Error cause. */ - explicit ignite_error(status_code statusCode, std::string message, std::exception_ptr cause) noexcept - : m_status_code(statusCode) + explicit ignite_error(error::code code, std::string message, std::exception_ptr cause) noexcept + : m_status_code(code) , m_message(std::move(message)) , m_cause(std::move(cause)) {} // NOLINT(bugprone-throw-keyword-missing) @@ -92,7 +78,7 @@ public: * * @return Status code. */ - [[nodiscard]] status_code get_status_code() const noexcept { return m_status_code; } + [[nodiscard]] error::code get_status_code() const noexcept { return m_status_code; } /** * Get error cause. @@ -103,7 +89,7 @@ public: private: /** Status code. */ - status_code m_status_code{status_code::SUCCESS}; + error::code m_status_code{error::code::GENERIC}; /** Message. */ std::string m_message; diff --git a/modules/platforms/cpp/ignite/common/ignite_result.h b/modules/platforms/cpp/ignite/common/ignite_result.h index 52ae0b27d7..b04b6dd065 100644 --- a/modules/platforms/cpp/ignite/common/ignite_result.h +++ b/modules/platforms/cpp/ignite/common/ignite_result.h @@ -239,9 +239,9 @@ ignite_result<T> result_of_operation(const std::function<T()> &operation) noexce } catch (const std::exception &err) { std::string msg("Standard library exception is thrown: "); msg += err.what(); - return {ignite_error(status_code::GENERIC, msg, std::current_exception())}; + return {ignite_error(error::code::GENERIC, msg, std::current_exception())}; } catch (...) { - return {ignite_error(status_code::UNKNOWN, "Unknown error is encountered when processing network event", + return {ignite_error(error::code::INTERNAL, "Unknown error is encountered when processing network event", std::current_exception())}; } } diff --git a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.cpp b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.cpp index 9ec272fb3a..f9ac4ae128 100644 --- a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.cpp +++ b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.cpp @@ -39,8 +39,7 @@ linux_async_client::linux_async_client(int fd, end_point addr, tcp_range range) , m_range(std::move(range)) , m_send_packets() , m_send_mutex() - , m_recv_packet(BUFFER_SIZE) - , m_close_err() { + , m_recv_packet(BUFFER_SIZE) { } linux_async_client::~linux_async_client() { @@ -54,7 +53,7 @@ bool linux_async_client::shutdown(std::optional<ignite_error> err) { if (m_state != state::CONNECTED) return false; - m_close_err = err ? std::move(*err) : ignite_error("Connection closed by application"); + m_close_err = std::move(err); ::shutdown(m_fd, SHUT_RDWR); m_state = state::SHUTDOWN; diff --git a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.h b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.h index 4b771f38ce..217d9d8b05 100644 --- a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.h +++ b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client.h @@ -172,7 +172,7 @@ public: * * @return Connection error. */ - [[nodiscard]] const ignite_error &get_close_error() const { return m_close_err; } + [[nodiscard]] std::optional<ignite_error> get_close_error() const { return m_close_err; } private: /** @@ -211,7 +211,7 @@ private: std::vector<std::byte> m_recv_packet; /** Closing error. */ - ignite_error m_close_err; + std::optional<ignite_error> m_close_err {}; }; } // namespace ignite::network::detail diff --git a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client_pool.cpp b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client_pool.cpp index 9ca6d2c06d..15739bab43 100644 --- a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client_pool.cpp +++ b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_client_pool.cpp @@ -96,13 +96,7 @@ void linux_async_client_pool::close_and_release(uint64_t id, std::optional<ignit bool closed = client->close(); if (closed) { - ignite_error err0(client->get_close_error()); - if (err0.get_status_code() == status_code::SUCCESS) - err0 = ignite_error(status_code::NETWORK, "Connection closed by server"); - - if (!err) - err = std::move(err0); - + err = client->get_close_error(); handle_connection_closed(id, err); } } diff --git a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_worker_thread.cpp b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_worker_thread.cpp index 2145af8dfe..1c5001545d 100644 --- a/modules/platforms/cpp/ignite/network/detail/linux/linux_async_worker_thread.cpp +++ b/modules/platforms/cpp/ignite/network/detail/linux/linux_async_worker_thread.cpp @@ -66,7 +66,7 @@ void linux_async_worker_thread::start(size_t limit, std::vector<tcp_range> addrs if (m_stop_event < 0) { std::string msg = get_last_system_error("Failed to create stop event instance", ""); close(m_stop_event); - throw ignite_error(status_code::OS, msg); + throw ignite_error(error::code::INTERNAL, msg); } epoll_event event{}; @@ -79,7 +79,7 @@ void linux_async_worker_thread::start(size_t limit, std::vector<tcp_range> addrs std::string msg = get_last_system_error("Failed to create stop event instance", ""); close(m_stop_event); close(m_epoll); - throw ignite_error(status_code::OS, msg); + throw ignite_error(error::code::INTERNAL, msg); } m_stopping = false; @@ -246,7 +246,7 @@ void linux_async_worker_thread::handle_connection_events() { } void linux_async_worker_thread::report_connection_error(const end_point &addr, std::string msg) { - ignite_error err(status_code::NETWORK, std::move(msg)); + ignite_error err(error::code::CONNECTION, std::move(msg)); m_client_pool.handle_connection_error(addr, err); } diff --git a/modules/platforms/cpp/ignite/network/detail/linux/tcp_socket_client.h b/modules/platforms/cpp/ignite/network/detail/linux/tcp_socket_client.h index f491f1f6a7..7870e46f01 100644 --- a/modules/platforms/cpp/ignite/network/detail/linux/tcp_socket_client.h +++ b/modules/platforms/cpp/ignite/network/detail/linux/tcp_socket_client.h @@ -80,7 +80,7 @@ public: int res = getaddrinfo(hostname, str_port.c_str(), &hints, &result); if (res != 0) - throw ignite_error(status_code::NETWORK, + throw ignite_error(error::code::CONNECTION, "Can not resolve host: " + std::string(hostname) + ":" + str_port + ", error_code=" + std::to_string(res)); @@ -99,7 +99,7 @@ public: if (m_socket_handle == SOCKET_ERROR) throw ignite_error( - status_code::OS, "Socket creation failed: " + detail::get_last_socket_error_message()); + error::code::CONNECTION, "Socket creation failed: " + detail::get_last_socket_error_message()); detail::try_set_socket_options(m_socket_handle, BUFFER_SIZE, true, true, true); @@ -136,7 +136,7 @@ public: if (is_timeout) return false; - throw ignite_error(status_code::NETWORK, last_err_msg); + throw ignite_error(error::code::CONNECTION, last_err_msg); } return true; diff --git a/modules/platforms/cpp/ignite/network/detail/utils.h b/modules/platforms/cpp/ignite/network/detail/utils.h index a984ed7241..3348cd7733 100644 --- a/modules/platforms/cpp/ignite/network/detail/utils.h +++ b/modules/platforms/cpp/ignite/network/detail/utils.h @@ -104,7 +104,7 @@ inline std::string get_last_system_error(std::string_view description, std::stri * @param advice User advice. */ inline void throw_last_system_error(std::string_view description, std::string_view advice = {}) { - throw ignite_error(status_code::OS, get_last_system_error(description, advice)); + throw ignite_error(error::code::INTERNAL, get_last_system_error(description, advice)); } /** diff --git a/modules/platforms/cpp/ignite/network/error_handling_filter.cpp b/modules/platforms/cpp/ignite/network/error_handling_filter.cpp index 2a4079e0ab..ad2c6a0ba8 100644 --- a/modules/platforms/cpp/ignite/network/error_handling_filter.cpp +++ b/modules/platforms/cpp/ignite/network/error_handling_filter.cpp @@ -55,10 +55,10 @@ void error_handling_filter::close_connection_on_exception(uint64_t id, const std } catch (std::exception &err) { std::string msg("Standard library exception is thrown: "); msg += err.what(); - ignite_error err0(status_code::GENERIC, msg); + ignite_error err0(error::code::GENERIC, msg); data_filter_adapter::close(id, std::move(err0)); } catch (...) { - ignite_error err0(status_code::UNKNOWN, "Unknown error is encountered when processing network event"); + ignite_error err0(error::code::INTERNAL, "Unknown error is encountered when processing network event"); data_filter_adapter::close(id, std::move(err0)); } } diff --git a/modules/platforms/cpp/ignite/odbc/common_types.cpp b/modules/platforms/cpp/ignite/odbc/common_types.cpp index ed66231f67..d91007f132 100644 --- a/modules/platforms/cpp/ignite/odbc/common_types.cpp +++ b/modules/platforms/cpp/ignite/odbc/common_types.cpp @@ -109,6 +109,186 @@ environment_attribute environment_attribute_to_internal(int32_t attr) { return environment_attribute::UNKNOWN; } +sql_state error_code_to_sql_state(error::code code) { + switch (code) { + // Common group. Group code: 1 + case error::code::NODE_STOPPING: + case error::code::COMPONENT_NOT_STARTED: + case error::code::ILLEGAL_ARGUMENT: + case error::code::SSL_CONFIGURATION: + case error::code::NODE_LEFT: + case error::code::INTERNAL: + return sql_state::SHY000_GENERAL_ERROR; + + // Table group. Group code: 2 + case error::code::TABLE_ALREADY_EXISTS: + return sql_state::S42S01_TABLE_OR_VIEW_ALREADY_EXISTS; + case error::code::TABLE_NOT_FOUND: + return sql_state::S42S02_TABLE_OR_VIEW_NOT_FOUND; + case error::code::COLUMN_ALREADY_EXISTS: + return sql_state::S42S21_COLUMN_ALREADY_EXISTS; + case error::code::COLUMN_NOT_FOUND: + return sql_state::S42S22_COLUMN_NOT_FOUND; + case error::code::TABLE_STOPPING: + case error::code::TABLE_DEFINITION: + case error::code::SCHEMA_VERSION_MISMATCH: + return sql_state::SHY000_GENERAL_ERROR; + + // Client group. Group code: 3 + case error::code::CONNECTION: + case error::code::PROTOCOL: + case error::code::PROTOCOL_COMPATIBILITY: + return sql_state::S08001_CANNOT_CONNECT; + case error::code::TABLE_ID_NOT_FOUND: + return sql_state::S42S02_TABLE_OR_VIEW_NOT_FOUND; + case error::code::AUTHENTICATION: + case error::code::AUTHORIZATION: + case error::code::CONFIGURATION: + case error::code::CLUSTER_ID_MISMATCH: + case error::code::CLIENT_SSL_CONFIGURATION: + case error::code::HANDSHAKE_HEADER: + return sql_state::S08004_CONNECTION_REJECTED; + + // Sql group. Group code: 4 + case error::code::CURSOR_CLOSED: + return sql_state::S24000_INVALID_CURSOR_STATE; + case error::code::CURSOR_NO_MORE_PAGES: + return sql_state::S24000_INVALID_CURSOR_STATE; + case error::code::SCHEMA_NOT_FOUND: + return sql_state::S3F000_INVALID_SCHEMA_NAME; + case error::code::PLANNING_TIMEOUT: + return sql_state::SHYT00_TIMEOUT_EXPIRED; + case error::code::EXECUTION_CANCELLED: + return sql_state::SHY008_OPERATION_CANCELED; + case error::code::TX_CONTROL_INSIDE_EXTERNAL_TX: + return sql_state::S25000_INVALID_TRANSACTION_STATE; + case error::code::CONSTRAINT_VIOLATION: + return sql_state::S23000_INTEGRITY_CONSTRAINT_VIOLATION; + case error::code::STMT_PARSE: + return sql_state::S42000_SYNTAX_ERROR_OR_ACCESS_VIOLATION; + case error::code::STMT_VALIDATION: + return sql_state::S42000_SYNTAX_ERROR_OR_ACCESS_VIOLATION; + case error::code::QUERY_NO_RESULT_SET: + case error::code::RUNTIME: + case error::code::SESSION_CLOSED: + case error::code::MAPPING: + return sql_state::SHY000_GENERAL_ERROR; + + // MetaStorage group. Group code: 5 + case error::code::OP_EXECUTION: + case error::code::OP_EXECUTION_TIMEOUT: + return sql_state::SHYT00_TIMEOUT_EXPIRED; + case error::code::STARTING_STORAGE: + case error::code::RESTORING_STORAGE: + case error::code::COMPACTION: + return sql_state::SHY000_GENERAL_ERROR; + + // Index group. Group code: 6 + case error::code::INDEX_NOT_FOUND: + return sql_state::S42S12_INDEX_NOT_FOUND; + case error::code::INDEX_ALREADY_EXISTS: + return sql_state::S42S11_INDEX_ALREADY_EXISTS; + case error::code::INVALID_INDEX_DEFINITION: + return sql_state::SHY000_GENERAL_ERROR; + + // Transactions group. Group code: 7 + case error::code::TX_STATE_STORAGE: + case error::code::TX_STATE_STORAGE_STOPPED: + case error::code::TX_UNEXPECTED_STATE: + case error::code::ACQUIRE_LOCK: + case error::code::ACQUIRE_LOCK_TIMEOUT: + case error::code::TX_COMMIT: + case error::code::TX_ROLLBACK: + case error::code::TX_FAILED_READ_WRITE_OPERATION: + case error::code::TX_REPLICA_UNAVAILABLE: + case error::code::TX_STATE_STORAGE_REBALANCE: + case error::code::TX_READ_ONLY_TOO_OLD: + case error::code::TX_INCOMPATIBLE_SCHEMA: + case error::code::TX_PRIMARY_REPLICA_EXPIRED: + return sql_state::S25000_INVALID_TRANSACTION_STATE; + + // Replicator group. Group code: 8 + case error::code::CURSOR_CLOSE: + return sql_state::S24000_INVALID_CURSOR_STATE; + case error::code::REPLICA_TIMEOUT: + return sql_state::SHYT00_TIMEOUT_EXPIRED; + case error::code::REPLICA_COMMON: + case error::code::REPLICA_IS_ALREADY_STARTED: + case error::code::REPLICA_UNSUPPORTED_REQUEST: + case error::code::REPLICA_UNAVAILABLE: + case error::code::REPLICA_MISS: + case error::code::REPLICA_STOPPING: + case error::code::REPLICATION_SAFE_TIME_REORDERING: + return sql_state::SHY000_GENERAL_ERROR; + + // Storage group. Group code: 9 + case error::code::GENERIC: + case error::code::DIRECTORY_CREATION: + case error::code::ALREADY_CLOSED: + case error::code::STORAGE_REBALANCE: + return sql_state::SHY000_GENERAL_ERROR; + + // DistributionZones group. Group code: 10 + case error::code::ZONE_ALREADY_EXISTS: + case error::code::ZONE_NOT_FOUND: + case error::code::ZONE_RENAME: + case error::code::ZONE_DROP: + case error::code::ZONE_DEFINITION: + return sql_state::SHY000_GENERAL_ERROR; + + // Network group. Group code: 11 + case error::code::UNRESOLVABLE_CONSISTENT_ID: + case error::code::PORT_IN_USE: + return sql_state::S08001_CANNOT_CONNECT; + + // NodeConfiguration group. Group code: 12 + case error::code::CONFIG_READ: + case error::code::CONFIG_FILE_CREATE: + case error::code::CONFIG_WRITE: + case error::code::CONFIG_PARSE: + return sql_state::SHY000_GENERAL_ERROR; + + // CodeDeployment group. Group code: 13 + case error::code::UNIT_NOT_FOUND: + case error::code::UNIT_ALREADY_EXISTS: + case error::code::UNIT_CONTENT_READ: + case error::code::UNIT_UNAVAILABLE: + return sql_state::SHY000_GENERAL_ERROR; + + // GarbageCollector group. Group code: 14 + case error::code::CLOSED: + return sql_state::SHY000_GENERAL_ERROR; + + // Authentication group. Group code: 15 + case error::code::UNSUPPORTED_AUTHENTICATION_TYPE: + case error::code::INVALID_CREDENTIALS: + case error::code::BASIC_PROVIDER: + return sql_state::S08004_CONNECTION_REJECTED; + + // Compute group. Group code: 16 + case error::code::CLASS_PATH: + case error::code::CLASS_LOADER: + case error::code::CLASS_INITIALIZATION: + case error::code::QUEUE_OVERFLOW: + case error::code::COMPUTE_JOB_STATE_TRANSITION: + case error::code::CANCELLING: + case error::code::RESULT_NOT_FOUND: + return sql_state::SHY000_GENERAL_ERROR; + + // Catalog group. Group code: 17 + case error::code::VALIDATION: + return sql_state::SHY000_GENERAL_ERROR; + + // PlacementDriver group. Group code: 18 + case error::code::PRIMARY_REPLICA_AWAIT_TIMEOUT: + return sql_state::SHYT00_TIMEOUT_EXPIRED; + case error::code::PRIMARY_REPLICA_AWAIT: + return sql_state::SHY000_GENERAL_ERROR; + } + + return sql_state::SHY000_GENERAL_ERROR; +} + sql_state response_status_to_sql_state(int32_t status) { switch (response_status(status)) { case response_status::PARSING_FAILURE: diff --git a/modules/platforms/cpp/ignite/odbc/common_types.h b/modules/platforms/cpp/ignite/odbc/common_types.h index e1ec923b53..cc0ba56b22 100644 --- a/modules/platforms/cpp/ignite/odbc/common_types.h +++ b/modules/platforms/cpp/ignite/odbc/common_types.h @@ -17,6 +17,7 @@ #pragma once +#include "ignite/common/error_codes.h" #include "ignite/odbc/system/odbc_constants.h" #include <cstdint> @@ -397,4 +398,12 @@ environment_attribute environment_attribute_to_internal(std::int32_t attr); */ sql_state response_status_to_sql_state(std::int32_t status); +/** + * Convert internal error code to SQL state. + * + * @param status error code. + * @return SQL state. + */ +sql_state error_code_to_sql_state(error::code code); + } // namespace ignite diff --git a/modules/platforms/cpp/ignite/odbc/diagnostic/diagnosable.h b/modules/platforms/cpp/ignite/odbc/diagnostic/diagnosable.h index a4f8cf1d0e..85d0faab33 100644 --- a/modules/platforms/cpp/ignite/odbc/diagnostic/diagnosable.h +++ b/modules/platforms/cpp/ignite/odbc/diagnostic/diagnosable.h @@ -95,7 +95,7 @@ public: add_status_record(err); return false; } catch (const ignite_error &err) { - add_status_record(sql_state::SHY000_GENERAL_ERROR, err.what_str()); + add_status_record(error_code_to_sql_state(err.get_status_code()), err.what_str()); return false; } diff --git a/modules/platforms/cpp/ignite/odbc/sql_connection.cpp b/modules/platforms/cpp/ignite/odbc/sql_connection.cpp index a5bb4b2521..143aa25253 100644 --- a/modules/platforms/cpp/ignite/odbc/sql_connection.cpp +++ b/modules/platforms/cpp/ignite/odbc/sql_connection.cpp @@ -351,7 +351,7 @@ network::data_buffer_owning sql_connection::receive_message(std::int64_t id, std if (test_flag(flags, protocol::response_flag::ERROR_FLAG)) { auto err = protocol::read_error(reader); - throw odbc_error(sql_state::SHY000_GENERAL_ERROR, err.what_str()); + throw odbc_error(error_code_to_sql_state(err.get_status_code()), err.what_str()); } return network::data_buffer_owning{std::move(res), reader.position()}; diff --git a/modules/platforms/cpp/ignite/odbc/sql_statement.cpp b/modules/platforms/cpp/ignite/odbc/sql_statement.cpp index e2e199c95e..7d555cc172 100644 --- a/modules/platforms/cpp/ignite/odbc/sql_statement.cpp +++ b/modules/platforms/cpp/ignite/odbc/sql_statement.cpp @@ -815,7 +815,7 @@ sql_result sql_statement::internal_get_column_attribute(uint16_t column_idx, uin return sql_result::AI_ERROR; if (column_idx > meta->size() || column_idx < 1) { - add_status_record(sql_state::SHY000_GENERAL_ERROR, "Column index is out of range.", 0, column_idx); + add_status_record(sql_state::S42S22_COLUMN_NOT_FOUND, "Column index is out of range.", 0, column_idx); return sql_result::AI_ERROR; } diff --git a/modules/platforms/cpp/ignite/protocol/utils.cpp b/modules/platforms/cpp/ignite/protocol/utils.cpp index 0ceec15eae..7e4e41271b 100644 --- a/modules/platforms/cpp/ignite/protocol/utils.cpp +++ b/modules/platforms/cpp/ignite/protocol/utils.cpp @@ -18,6 +18,8 @@ #include "ignite/protocol/utils.h" #include "ignite/protocol/reader.h" +#include "ignite/common/error_codes.h" + #include <msgpack.h> #include <limits> @@ -216,7 +218,7 @@ ignite_error read_error(reader &reader) { err_msg_builder << ": " << *message; err_msg_builder << " (" << code << ", " << trace_id << ")"; - return ignite_error{status_code(code), err_msg_builder.str()}; + return ignite_error{error::code(code), err_msg_builder.str()}; } void claim_primitive_with_type(binary_tuple_builder &builder, const primitive &value) { diff --git a/modules/platforms/cpp/tests/client-test/sql_test.cpp b/modules/platforms/cpp/tests/client-test/sql_test.cpp index 95d375ab5a..4cf57d2885 100644 --- a/modules/platforms/cpp/tests/client-test/sql_test.cpp +++ b/modules/platforms/cpp/tests/client-test/sql_test.cpp @@ -290,8 +290,9 @@ TEST_F(sql_test, sql_create_existing_table) { try { m_client.get_sql().execute(nullptr, {"CREATE TABLE TEST(ID INT PRIMARY KEY, VAL VARCHAR)"}, {}); } catch (const ignite_error &e) { - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Table with name 'PUBLIC.TEST' already exists")); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION); throw; } }, @@ -304,8 +305,9 @@ TEST_F(sql_test, sql_add_existing_column) { try { m_client.get_sql().execute(nullptr, {"ALTER TABLE TEST ADD COLUMN ID INT"}, {}); } catch (const ignite_error &e) { - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Column with name 'ID' already exists")); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION); throw; } }, @@ -318,8 +320,9 @@ TEST_F(sql_test, sql_alter_nonexisting_table) { try { m_client.get_sql().execute(nullptr, {"ALTER TABLE UNKNOWN_TABLE ADD COLUMN ID INT"}, {}); } catch (const ignite_error &e) { - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Table with name 'PUBLIC.UNKNOWN_TABLE' not found")); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION); throw; } }, diff --git a/modules/platforms/cpp/tests/odbc-test/error_test.cpp b/modules/platforms/cpp/tests/odbc-test/error_test.cpp index 5132148e42..dafe406272 100644 --- a/modules/platforms/cpp/tests/odbc-test/error_test.cpp +++ b/modules/platforms/cpp/tests/odbc-test/error_test.cpp @@ -79,8 +79,7 @@ TEST_F(error_test, duplicate_key) { ret = SQLExecDirect(m_statement, insert_req, SQL_NTS); ASSERT_EQ(ret, SQL_ERROR); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "HY000"); + EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "23000"); } TEST_F(error_test, update_key) { @@ -98,8 +97,8 @@ TEST_F(error_test, update_key) { ret = SQLExecDirect(m_statement, update_req, SQL_NTS); ASSERT_EQ(ret, SQL_ERROR); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "HY000"); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "42000"); } TEST_F(error_test, table_not_found) { @@ -112,8 +111,8 @@ TEST_F(error_test, table_not_found) { ret = SQLExecDirect(m_statement, req, SQL_NTS); ASSERT_EQ(ret, SQL_ERROR); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "HY000"); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "42000"); std::string error = get_odbc_error_message(SQL_HANDLE_STMT, m_statement); EXPECT_THAT(error, testing::HasSubstr("Table with name 'PUBLIC.NONEXISTING' not found")); @@ -143,8 +142,8 @@ TEST_F(error_test, index_not_found) { ret = SQLExecDirect(m_statement, req, SQL_NTS); ASSERT_EQ(ret, SQL_ERROR); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "HY000"); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "42000"); } TEST_F(error_test, syntax_error) { @@ -157,6 +156,6 @@ TEST_F(error_test, syntax_error) { ret = SQLExecDirect(m_statement, req, SQL_NTS); ASSERT_EQ(ret, SQL_ERROR); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "HY000"); + // TODO: IGNITE-21217 Check STMT_VALIDATION error code usage + EXPECT_EQ(get_odbc_error_state(SQL_HANDLE_STMT, m_statement), "42000"); } diff --git a/modules/platforms/cpp/tests/odbc-test/transaction_test.cpp b/modules/platforms/cpp/tests/odbc-test/transaction_test.cpp index 16dace0f3e..ea416dddfd 100644 --- a/modules/platforms/cpp/tests/odbc-test/transaction_test.cpp +++ b/modules/platforms/cpp/tests/odbc-test/transaction_test.cpp @@ -576,8 +576,7 @@ TEST_F(transaction_test, transaction_error) { insert_test_value(conn2.m_statement, 2, "test_2"); } catch (const odbc_exception &err) { EXPECT_THAT(err.message, testing::HasSubstr("Failed to acquire a lock due to a possible deadlock")); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(err.sql_state, "HY000"); + EXPECT_EQ(err.sql_state, "25000"); throw; } }, @@ -594,8 +593,7 @@ TEST_F(transaction_test, transaction_error) { insert_test_value(conn2.m_statement, 2, "test_2"); } catch (const odbc_exception &err) { EXPECT_THAT(err.message, testing::HasSubstr("Transaction is already finished")); - // TODO: IGNITE-19944 Propagate SQL errors from engine to driver - EXPECT_EQ(err.sql_state, "HY000"); + EXPECT_EQ(err.sql_state, "25000"); throw; } }, diff --git a/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs b/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs deleted file mode 100644 index d1c25d5872..0000000000 --- a/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Internal.Generators -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Reflection; - using System.Text; - using System.Text.RegularExpressions; - using Microsoft.CodeAnalysis; - - /// <summary> - /// Generates error groups source from ErrorGroups.java. - /// </summary> - [Generator] - public sealed class ErrorGroupsGenerator : JavaToCsharpGeneratorBase - { - /// <inheritdoc/> - protected override IEnumerable<(string Name, string Code)> ExecuteInternal(GeneratorExecutionContext context) - { - var javaErrorGroupsFile = Path.GetFullPath(Path.Combine( - context.GetJavaModulesDirectory(), - "api", - "src", - "main", - "java", - "org", - "apache", - "ignite", - "lang", - "ErrorGroups.java")); - - if (!File.Exists(javaErrorGroupsFile)) - { - throw new Exception("File not found: " + javaErrorGroupsFile + " = " + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!); - } - - var javaErrorGroupsText = File.ReadAllText(javaErrorGroupsFile); - - // ErrorGroup TX_ERR_GROUP = ErrorGroup.newGroup("TX", 7); - var javaErrorGroups = Regex.Matches( - javaErrorGroupsText, - @"public static class ([A-Za-z]+) {\s+/\*\*.*?\*/\s+public static final ErrorGroup ([\w_]+)_ERR_GROUP = registerGroup\(""([\w_]+)"", \(short\)\s*(\d+)", - RegexOptions.Singleline | RegexOptions.CultureInvariant) - .Cast<Match>() - .Select(x => (ClassName: x.Groups[1].Value, GroupName: x.Groups[2].Value, ShortGroupName: x.Groups[3].Value, Code: short.Parse(x.Groups[4].Value, CultureInfo.InvariantCulture))) - .ToList(); - - if (javaErrorGroups.Count == 0) - { - throw new Exception($"Failed to parse Java error groups from '{javaErrorGroupsFile}'"); - } - - var sb = new StringBuilder(); - - sb.AppendLine("// <auto-generated/>"); - sb.AppendLine("namespace Apache.Ignite"); - sb.AppendLine("{"); - sb.AppendLine(" using System;\n"); - sb.AppendLine(" public static partial class ErrorGroups"); - sb.AppendLine(" {"); - - // GetGroupName. - sb.AppendLine( -@" /// <summary> - /// Gets the group name by code. - /// </summary> - /// <param name=""groupCode"">Group code.</param> - /// <returns>Group name.</returns> - public static string GetGroupName(int groupCode) => groupCode switch - {"); - - foreach (var (className, _, _, _) in javaErrorGroups) - { - sb.AppendLine(@$" {className}.GroupCode => {className}.GroupName,"); - } - - sb.AppendLine( - @" - _ => UnknownGroupName - };"); - - // Groups. - foreach (var (className, groupName, shortGroupName, groupCode) in javaErrorGroups) - { - sb.AppendLine(); - sb.AppendLine($" /// <summary> {className} errors. </summary>"); - sb.AppendLine($" public static class {className}"); - sb.AppendLine($" {{"); - sb.AppendLine($" /// <summary> {className} group code. </summary>"); - sb.AppendLine($" public const short GroupCode = {groupCode};"); - sb.AppendLine(); - sb.AppendLine($" /// <summary> {className} group name. </summary>"); - sb.AppendLine($" public const string GroupName = \"{shortGroupName}\";"); - - // TX_STATE_STORAGE_CREATE_ERR = TX_ERR_GROUP.registerErrorCode(1) - var javaErrors = Regex.Matches( - javaErrorGroupsText, - @"([\w_]+)_ERR = " + groupName + @"_ERR_GROUP\.registerErrorCode\(\(short\)\s*(\d+)\);") - .Cast<Match>() - .Select(x => (Name: x.Groups[1].Value, Code: short.Parse(x.Groups[2].Value, CultureInfo.InvariantCulture))) - .ToList(); - - if (javaErrors.Count == 0) - { - throw new Exception($"Failed to parse Java errors for group {groupName} from '{javaErrorGroupsFile}'"); - } - - foreach (var (errorName, errorCode) in javaErrors) - { - var dotNetErrorName = SnakeToCamelCase(errorName); - - sb.AppendLine(); - sb.AppendLine($" /// <summary> {dotNetErrorName} error. </summary>"); - sb.AppendLine($" public const int {dotNetErrorName} = (GroupCode << 16) | ({errorCode} & 0xFFFF);"); - } - - sb.AppendLine(" }"); - } - - sb.AppendLine(" }"); - sb.AppendLine("}"); - - yield return ("ErrorGroups.g.cs", sb.ToString()); - } - - private static string SnakeToCamelCase(string str) => - string.Concat(str.Split('_').Select(x => x.Substring(0, 1).ToUpperInvariant() + x.Substring(1).ToLowerInvariant())); - } -} diff --git a/modules/platforms/dotnet/Apache.Ignite/ErrorCodes.g.cs b/modules/platforms/dotnet/Apache.Ignite/ErrorCodes.g.cs new file mode 100644 index 0000000000..4d4c0c05be --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite/ErrorCodes.g.cs @@ -0,0 +1,531 @@ +/* + * 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. + */ + +// <auto-generated/> +namespace Apache.Ignite +{ + using System; + + public static partial class ErrorGroups + { + /// <summary> + /// Gets the group name by code. + /// </summary> + /// <param name="groupCode">Group code.</param> + /// <returns>Group name.</returns> + public static string GetGroupName(int groupCode) => groupCode switch + { + Common.GroupCode => Common.GroupName, + Table.GroupCode => Table.GroupName, + Client.GroupCode => Client.GroupName, + Sql.GroupCode => Sql.GroupName, + MetaStorage.GroupCode => MetaStorage.GroupName, + Index.GroupCode => Index.GroupName, + Transactions.GroupCode => Transactions.GroupName, + Replicator.GroupCode => Replicator.GroupName, + Storage.GroupCode => Storage.GroupName, + DistributionZones.GroupCode => DistributionZones.GroupName, + Network.GroupCode => Network.GroupName, + NodeConfiguration.GroupCode => NodeConfiguration.GroupName, + CodeDeployment.GroupCode => CodeDeployment.GroupName, + GarbageCollector.GroupCode => GarbageCollector.GroupName, + Authentication.GroupCode => Authentication.GroupName, + Compute.GroupCode => Compute.GroupName, + Catalog.GroupCode => Catalog.GroupName, + PlacementDriver.GroupCode => PlacementDriver.GroupName, + + _ => UnknownGroupName + }; + + /// <summary> Common errors. </summary> + public static class Common + { + /// <summary> Common group code. </summary> + public const short GroupCode = 1; + + /// <summary> Common group name. </summary> + public const String GroupName = "CMN"; + + /// <summary> NodeStopping error. </summary> + public const int NodeStopping = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> ComponentNotStarted error. </summary> + public const int ComponentNotStarted = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> IllegalArgument error. </summary> + public const int IllegalArgument = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> SslConfiguration error. </summary> + public const int SslConfiguration = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> NodeLeft error. </summary> + public const int NodeLeft = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> Internal error. </summary> + public const int Internal = (GroupCode << 16) | (65535 & 0xFFFF); + } + + /// <summary> Table errors. </summary> + public static class Table + { + /// <summary> Table group code. </summary> + public const short GroupCode = 2; + + /// <summary> Table group name. </summary> + public const String GroupName = "TBL"; + + /// <summary> TableAlreadyExists error. </summary> + public const int TableAlreadyExists = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> TableNotFound error. </summary> + public const int TableNotFound = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ColumnAlreadyExists error. </summary> + public const int ColumnAlreadyExists = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> ColumnNotFound error. </summary> + public const int ColumnNotFound = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> TableStopping error. </summary> + public const int TableStopping = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> TableDefinition error. </summary> + public const int TableDefinition = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> SchemaVersionMismatch error. </summary> + public const int SchemaVersionMismatch = (GroupCode << 16) | (7 & 0xFFFF); + } + + /// <summary> Client errors. </summary> + public static class Client + { + /// <summary> Client group code. </summary> + public const short GroupCode = 3; + + /// <summary> Client group name. </summary> + public const String GroupName = "CLIENT"; + + /// <summary> Connection error. </summary> + public const int Connection = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> Protocol error. </summary> + public const int Protocol = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ProtocolCompatibility error. </summary> + public const int ProtocolCompatibility = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> TableIdNotFound error. </summary> + public const int TableIdNotFound = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> Authentication error. </summary> + public const int Authentication = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> Authorization error. </summary> + public const int Authorization = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> Configuration error. </summary> + public const int Configuration = (GroupCode << 16) | (7 & 0xFFFF); + + /// <summary> ClusterIdMismatch error. </summary> + public const int ClusterIdMismatch = (GroupCode << 16) | (8 & 0xFFFF); + + /// <summary> ClientSslConfiguration error. </summary> + public const int ClientSslConfiguration = (GroupCode << 16) | (9 & 0xFFFF); + + /// <summary> HandshakeHeader error. </summary> + public const int HandshakeHeader = (GroupCode << 16) | (10 & 0xFFFF); + } + + /// <summary> Sql errors. </summary> + public static class Sql + { + /// <summary> Sql group code. </summary> + public const short GroupCode = 4; + + /// <summary> Sql group name. </summary> + public const String GroupName = "SQL"; + + /// <summary> CursorNoMorePages error. </summary> + public const int CursorNoMorePages = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> QueryNoResultSet error. </summary> + public const int QueryNoResultSet = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> SchemaNotFound error. </summary> + public const int SchemaNotFound = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> CursorClosed error. </summary> + public const int CursorClosed = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> StmtParse error. </summary> + public const int StmtParse = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> StmtValidation error. </summary> + public const int StmtValidation = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> ConstraintViolation error. </summary> + public const int ConstraintViolation = (GroupCode << 16) | (7 & 0xFFFF); + + /// <summary> ExecutionCancelled error. </summary> + public const int ExecutionCancelled = (GroupCode << 16) | (8 & 0xFFFF); + + /// <summary> Runtime error. </summary> + public const int Runtime = (GroupCode << 16) | (9 & 0xFFFF); + + /// <summary> PlanningTimeout error. </summary> + public const int PlanningTimeout = (GroupCode << 16) | (10 & 0xFFFF); + + /// <summary> SessionClosed error. </summary> + public const int SessionClosed = (GroupCode << 16) | (11 & 0xFFFF); + + /// <summary> Mapping error. </summary> + public const int Mapping = (GroupCode << 16) | (12 & 0xFFFF); + + /// <summary> TxControlInsideExternalTx error. </summary> + public const int TxControlInsideExternalTx = (GroupCode << 16) | (13 & 0xFFFF); + } + + /// <summary> MetaStorage errors. </summary> + public static class MetaStorage + { + /// <summary> MetaStorage group code. </summary> + public const short GroupCode = 5; + + /// <summary> MetaStorage group name. </summary> + public const String GroupName = "META"; + + /// <summary> StartingStorage error. </summary> + public const int StartingStorage = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> RestoringStorage error. </summary> + public const int RestoringStorage = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> Compaction error. </summary> + public const int Compaction = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> OpExecution error. </summary> + public const int OpExecution = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> OpExecutionTimeout error. </summary> + public const int OpExecutionTimeout = (GroupCode << 16) | (5 & 0xFFFF); + } + + /// <summary> Index errors. </summary> + public static class Index + { + /// <summary> Index group code. </summary> + public const short GroupCode = 6; + + /// <summary> Index group name. </summary> + public const String GroupName = "IDX"; + + /// <summary> InvalidIndexDefinition error. </summary> + public const int InvalidIndexDefinition = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> IndexNotFound error. </summary> + public const int IndexNotFound = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> IndexAlreadyExists error. </summary> + public const int IndexAlreadyExists = (GroupCode << 16) | (3 & 0xFFFF); + } + + /// <summary> Transactions errors. </summary> + public static class Transactions + { + /// <summary> Transactions group code. </summary> + public const short GroupCode = 7; + + /// <summary> Transactions group name. </summary> + public const String GroupName = "TX"; + + /// <summary> TxStateStorage error. </summary> + public const int TxStateStorage = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> TxStateStorageStopped error. </summary> + public const int TxStateStorageStopped = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> TxUnexpectedState error. </summary> + public const int TxUnexpectedState = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> AcquireLock error. </summary> + public const int AcquireLock = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> AcquireLockTimeout error. </summary> + public const int AcquireLockTimeout = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> TxCommit error. </summary> + public const int TxCommit = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> TxRollback error. </summary> + public const int TxRollback = (GroupCode << 16) | (7 & 0xFFFF); + + /// <summary> TxFailedReadWriteOperation error. </summary> + public const int TxFailedReadWriteOperation = (GroupCode << 16) | (8 & 0xFFFF); + + /// <summary> TxReplicaUnavailable error. </summary> + public const int TxReplicaUnavailable = (GroupCode << 16) | (9 & 0xFFFF); + + /// <summary> TxStateStorageRebalance error. </summary> + public const int TxStateStorageRebalance = (GroupCode << 16) | (10 & 0xFFFF); + + /// <summary> TxReadOnlyTooOld error. </summary> + public const int TxReadOnlyTooOld = (GroupCode << 16) | (11 & 0xFFFF); + + /// <summary> TxIncompatibleSchema error. </summary> + public const int TxIncompatibleSchema = (GroupCode << 16) | (12 & 0xFFFF); + + /// <summary> TxPrimaryReplicaExpired error. </summary> + public const int TxPrimaryReplicaExpired = (GroupCode << 16) | (13 & 0xFFFF); + } + + /// <summary> Replicator errors. </summary> + public static class Replicator + { + /// <summary> Replicator group code. </summary> + public const short GroupCode = 8; + + /// <summary> Replicator group name. </summary> + public const String GroupName = "REP"; + + /// <summary> ReplicaCommon error. </summary> + public const int ReplicaCommon = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> ReplicaIsAlreadyStarted error. </summary> + public const int ReplicaIsAlreadyStarted = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ReplicaTimeout error. </summary> + public const int ReplicaTimeout = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> ReplicaUnsupportedRequest error. </summary> + public const int ReplicaUnsupportedRequest = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> ReplicaUnavailable error. </summary> + public const int ReplicaUnavailable = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> ReplicaMiss error. </summary> + public const int ReplicaMiss = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> CursorClose error. </summary> + public const int CursorClose = (GroupCode << 16) | (7 & 0xFFFF); + + /// <summary> ReplicaStopping error. </summary> + public const int ReplicaStopping = (GroupCode << 16) | (8 & 0xFFFF); + + /// <summary> ReplicationSafeTimeReordering error. </summary> + public const int ReplicationSafeTimeReordering = (GroupCode << 16) | (9 & 0xFFFF); + } + + /// <summary> Storage errors. </summary> + public static class Storage + { + /// <summary> Storage group code. </summary> + public const short GroupCode = 9; + + /// <summary> Storage group name. </summary> + public const String GroupName = "STORAGE"; + + /// <summary> Generic error. </summary> + public const int Generic = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> DirectoryCreation error. </summary> + public const int DirectoryCreation = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> AlreadyClosed error. </summary> + public const int AlreadyClosed = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> StorageRebalance error. </summary> + public const int StorageRebalance = (GroupCode << 16) | (4 & 0xFFFF); + } + + /// <summary> DistributionZones errors. </summary> + public static class DistributionZones + { + /// <summary> DistributionZones group code. </summary> + public const short GroupCode = 10; + + /// <summary> DistributionZones group name. </summary> + public const String GroupName = "DISTRZONES"; + + /// <summary> ZoneAlreadyExists error. </summary> + public const int ZoneAlreadyExists = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> ZoneNotFound error. </summary> + public const int ZoneNotFound = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ZoneRename error. </summary> + public const int ZoneRename = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> ZoneDrop error. </summary> + public const int ZoneDrop = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> ZoneDefinition error. </summary> + public const int ZoneDefinition = (GroupCode << 16) | (5 & 0xFFFF); + } + + /// <summary> Network errors. </summary> + public static class Network + { + /// <summary> Network group code. </summary> + public const short GroupCode = 11; + + /// <summary> Network group name. </summary> + public const String GroupName = "NETWORK"; + + /// <summary> UnresolvableConsistentId error. </summary> + public const int UnresolvableConsistentId = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> PortInUse error. </summary> + public const int PortInUse = (GroupCode << 16) | (2 & 0xFFFF); + } + + /// <summary> NodeConfiguration errors. </summary> + public static class NodeConfiguration + { + /// <summary> NodeConfiguration group code. </summary> + public const short GroupCode = 12; + + /// <summary> NodeConfiguration group name. </summary> + public const String GroupName = "NODECFG"; + + /// <summary> ConfigRead error. </summary> + public const int ConfigRead = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> ConfigFileCreate error. </summary> + public const int ConfigFileCreate = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ConfigWrite error. </summary> + public const int ConfigWrite = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> ConfigParse error. </summary> + public const int ConfigParse = (GroupCode << 16) | (4 & 0xFFFF); + } + + /// <summary> CodeDeployment errors. </summary> + public static class CodeDeployment + { + /// <summary> CodeDeployment group code. </summary> + public const short GroupCode = 13; + + /// <summary> CodeDeployment group name. </summary> + public const String GroupName = "CODEDEPLOY"; + + /// <summary> UnitNotFound error. </summary> + public const int UnitNotFound = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> UnitAlreadyExists error. </summary> + public const int UnitAlreadyExists = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> UnitContentRead error. </summary> + public const int UnitContentRead = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> UnitUnavailable error. </summary> + public const int UnitUnavailable = (GroupCode << 16) | (4 & 0xFFFF); + } + + /// <summary> GarbageCollector errors. </summary> + public static class GarbageCollector + { + /// <summary> GarbageCollector group code. </summary> + public const short GroupCode = 14; + + /// <summary> GarbageCollector group name. </summary> + public const String GroupName = "GC"; + + /// <summary> Closed error. </summary> + public const int Closed = (GroupCode << 16) | (1 & 0xFFFF); + } + + /// <summary> Authentication errors. </summary> + public static class Authentication + { + /// <summary> Authentication group code. </summary> + public const short GroupCode = 15; + + /// <summary> Authentication group name. </summary> + public const String GroupName = "AUTHENTICATION"; + + /// <summary> UnsupportedAuthenticationType error. </summary> + public const int UnsupportedAuthenticationType = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> InvalidCredentials error. </summary> + public const int InvalidCredentials = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> BasicProvider error. </summary> + public const int BasicProvider = (GroupCode << 16) | (3 & 0xFFFF); + } + + /// <summary> Compute errors. </summary> + public static class Compute + { + /// <summary> Compute group code. </summary> + public const short GroupCode = 16; + + /// <summary> Compute group name. </summary> + public const String GroupName = "COMPUTE"; + + /// <summary> ClassPath error. </summary> + public const int ClassPath = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> ClassLoader error. </summary> + public const int ClassLoader = (GroupCode << 16) | (2 & 0xFFFF); + + /// <summary> ClassInitialization error. </summary> + public const int ClassInitialization = (GroupCode << 16) | (3 & 0xFFFF); + + /// <summary> QueueOverflow error. </summary> + public const int QueueOverflow = (GroupCode << 16) | (4 & 0xFFFF); + + /// <summary> ComputeJobStateTransition error. </summary> + public const int ComputeJobStateTransition = (GroupCode << 16) | (5 & 0xFFFF); + + /// <summary> Cancelling error. </summary> + public const int Cancelling = (GroupCode << 16) | (6 & 0xFFFF); + + /// <summary> ResultNotFound error. </summary> + public const int ResultNotFound = (GroupCode << 16) | (7 & 0xFFFF); + } + + /// <summary> Catalog errors. </summary> + public static class Catalog + { + /// <summary> Catalog group code. </summary> + public const short GroupCode = 17; + + /// <summary> Catalog group name. </summary> + public const String GroupName = "CATALOG"; + + /// <summary> Validation error. </summary> + public const int Validation = (GroupCode << 16) | (1 & 0xFFFF); + } + + /// <summary> PlacementDriver errors. </summary> + public static class PlacementDriver + { + /// <summary> PlacementDriver group code. </summary> + public const short GroupCode = 18; + + /// <summary> PlacementDriver group name. </summary> + public const String GroupName = "PLACEMENTDRIVER"; + + /// <summary> PrimaryReplicaAwaitTimeout error. </summary> + public const int PrimaryReplicaAwaitTimeout = (GroupCode << 16) | (1 & 0xFFFF); + + /// <summary> PrimaryReplicaAwait error. </summary> + public const int PrimaryReplicaAwait = (GroupCode << 16) | (2 & 0xFFFF); + } + } +} diff --git a/settings.gradle b/settings.gradle index 7d78fff869..abc5a1147c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -76,6 +76,7 @@ include(":ignite-arch-test") include(":ignite-file-transfer") include(":ignite-system-view") include(":ignite-system-view-api") +include(":ignite-error-code-annotation-processor") project(":ignite-examples").projectDir = file('examples') project(":ignite-dev-utilities").projectDir = file('dev-utilities') @@ -137,6 +138,7 @@ project(":ignite-arch-test").projectDir = file('modules/arch-test') project(":ignite-file-transfer").projectDir = file('modules/file-transfer') project(":ignite-system-view").projectDir = file('modules/system-view') project(":ignite-system-view-api").projectDir = file('modules/system-view-api') +project(":ignite-error-code-annotation-processor").projectDir = file('modules/error-code-annotation-processor') ext.isCiServer = System.getenv().containsKey("IGNITE_CI")