From a48bb62861d24e023ac31f2be1155f0ef91c6a14 Mon Sep 17 00:00:00 2001 From: Yihezkel Schoenbrun Date: Wed, 31 Aug 2022 15:39:21 +0300 Subject: [PATCH] Support tables with special characters .-_ (#269) * Support tables with special characters .-_ * Align normalizeEntityName with its C# equivalent --- .../azure/kusto/data/StringUtils.java | 19 ++++++++++++++++--- .../auth/endpoints/FastSuffixMatcher.java | 4 ++-- .../azure/kusto/quickstart/SampleApp.java | 16 ++++++++-------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/data/src/main/java/com/microsoft/azure/kusto/data/StringUtils.java b/data/src/main/java/com/microsoft/azure/kusto/data/StringUtils.java index 71589fcf..6ca6ec41 100644 --- a/data/src/main/java/com/microsoft/azure/kusto/data/StringUtils.java +++ b/data/src/main/java/com/microsoft/azure/kusto/data/StringUtils.java @@ -1,7 +1,11 @@ package com.microsoft.azure.kusto.data; -public class StringUtils { - public static String GetStringTail(String val, int minRuleLength) { +public class StringUtils extends org.apache.commons.lang3.StringUtils { + private StringUtils() { + // Hide constructor for static class + } + + public static String getStringTail(String val, int minRuleLength) { if (minRuleLength <= 0) { return ""; } @@ -13,6 +17,15 @@ public class StringUtils { return val.substring(val.length() - minRuleLength); } - private StringUtils() { + public static String normalizeEntityName(String name) { + if (StringUtils.isBlank(name)) { + return name; + } else if (name.startsWith("[")) { + return name; + } else if (!name.contains("'")) { + return "['" + name + "']"; + } else { + return "[\"" + name + "\"]"; + } } } diff --git a/data/src/main/java/com/microsoft/azure/kusto/data/auth/endpoints/FastSuffixMatcher.java b/data/src/main/java/com/microsoft/azure/kusto/data/auth/endpoints/FastSuffixMatcher.java index 97613c0b..c51989cb 100644 --- a/data/src/main/java/com/microsoft/azure/kusto/data/auth/endpoints/FastSuffixMatcher.java +++ b/data/src/main/java/com/microsoft/azure/kusto/data/auth/endpoints/FastSuffixMatcher.java @@ -28,7 +28,7 @@ public class FastSuffixMatcher { Map> processedRules = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); for (MatchRule rule : rules) { - String suffix = StringUtils.GetStringTail(rule.suffix, minRuleLength); + String suffix = StringUtils.getStringTail(rule.suffix, minRuleLength); List list = processedRules.computeIfAbsent(suffix, k -> new ArrayList<>()); list.add(rule.clone()); } @@ -77,7 +77,7 @@ public class FastSuffixMatcher { return new MatchResult(false, null); } - List matchRules = rules.get(StringUtils.GetStringTail(candidate, suffixLength)); + List matchRules = rules.get(StringUtils.getStringTail(candidate, suffixLength)); if (matchRules != null) { for (MatchRule rule : matchRules) { if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(candidate, rule.suffix)) { diff --git a/quickstart/src/main/java/com/microsoft/azure/kusto/quickstart/SampleApp.java b/quickstart/src/main/java/com/microsoft/azure/kusto/quickstart/SampleApp.java index ec975f9f..576c8ceb 100644 --- a/quickstart/src/main/java/com/microsoft/azure/kusto/quickstart/SampleApp.java +++ b/quickstart/src/main/java/com/microsoft/azure/kusto/quickstart/SampleApp.java @@ -5,11 +5,11 @@ import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.azure.kusto.data.Client; import com.microsoft.azure.kusto.data.ClientFactory; +import com.microsoft.azure.kusto.data.StringUtils; import com.microsoft.azure.kusto.ingest.IngestClient; import com.microsoft.azure.kusto.ingest.IngestClientFactory; import com.microsoft.azure.kusto.ingest.IngestionMapping; import com.microsoft.azure.kusto.ingest.IngestionProperties; -import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -41,7 +41,7 @@ enum SourceType { } /** - * AuthenticationModeOptions - represents the different options to autenticate to the system + * AuthenticationModeOptions - represents the different options to authenticate to the system */ enum AuthenticationModeOptions { USER_PROMPT("UserPrompt"), MANAGED_IDENTITY("ManagedIdentity"), APP_KEY("AppKey"), APP_CERTIFICATE("AppCertificate"); @@ -375,7 +375,7 @@ public class SampleApp { * @param tableSchema Table Schema */ private static void alterMergeExistingTableToProvidedSchema(Client kustoClient, String databaseName, String tableName, String tableSchema) { - String command = String.format(".alter-merge table %s %s", tableName, tableSchema); + String command = String.format(".alter-merge table %s %s", StringUtils.normalizeEntityName(tableName), tableSchema); Utils.Queries.executeCommand(kustoClient, databaseName, command); } @@ -387,7 +387,7 @@ public class SampleApp { * @param tableName Table name */ private static void queryExistingNumberOfRows(Client kustoClient, String databaseName, String tableName) { - String command = String.format("%s | count", tableName); + String command = String.format("%s | count", StringUtils.normalizeEntityName(tableName)); Utils.Queries.executeCommand(kustoClient, databaseName, command); } @@ -399,7 +399,7 @@ public class SampleApp { * @param tableName Table name */ private static void queryFirstTwoRows(Client kustoClient, String databaseName, String tableName) { - String command = String.format("%s | take 2", tableName); + String command = String.format("%s | take 2", StringUtils.normalizeEntityName(tableName)); Utils.Queries.executeCommand(kustoClient, databaseName, command); } @@ -412,7 +412,7 @@ public class SampleApp { * @param tableSchema Table Schema */ private static void createNewTable(Client kustoClient, String databaseName, String tableName, String tableSchema) { - String command = String.format(".create table %s %s", tableName, tableSchema); + String command = String.format(".create table %s %s", StringUtils.normalizeEntityName(tableName), tableSchema); Utils.Queries.executeCommand(kustoClient, databaseName, command); } @@ -430,7 +430,7 @@ public class SampleApp { * the default ingestion policy to ingest data after at most 10 seconds. Tip 2: This is generally a one-time configuration. Tip 3: You can also skip the * batching for some files using the Flush-Immediately property, though this option should be used with care as it is inefficient. */ - String command = String.format(".alter table %s policy ingestionbatching @'%s'", tableName, batchingPolicy); + String command = String.format(".alter table %s policy ingestionbatching @'%s'", StringUtils.normalizeEntityName(tableName), batchingPolicy); Utils.Queries.executeCommand(kustoClient, databaseName, command); // If it failed to alter the ingestion policy - it could be the result of insufficient permissions. The sample will still run, // though ingestion will be delayed for up to 5 minutes. @@ -485,7 +485,7 @@ public class SampleApp { waitForUserToProceed(String.format("Create a '%s' mapping reference named '%s'", ingestionMappingKind.getKustoValue(), mappingName)); mappingName = StringUtils.isNotBlank(mappingName) ? mappingName : "DefaultQuickstartMapping" + UUID.randomUUID().toString().substring(0, 5); - String mappingCommand = String.format(".create-or-alter table %s ingestion %s mapping '%s' '%s'", tableName, + String mappingCommand = String.format(".create-or-alter table %s ingestion %s mapping '%s' '%s'", StringUtils.normalizeEntityName(tableName), ingestionMappingKind.getKustoValue().toLowerCase(), mappingName, mappingValue); Utils.Queries.executeCommand(kustoClient, databaseName, mappingCommand); }