* Added formatter plugin, right now only starting

* Put config on main file

* Updated style to match ours better.

* Added declaration.

* edit build.yml

* Update style and apply formatting

* Update style and apply formatting

* Tweaked settings again

* Replace with session because that might be the correct path.

* Try formatting

* line endings

* renormalize new lines

* csluuid

* new lines

* new lines

* Run again with clean

* fixed build.yml

* Changed style to be better

* Added some docs
This commit is contained in:
AsafMah 2022-03-29 15:40:49 +03:00 коммит произвёл GitHub
Родитель 6745d593ec
Коммит f23b0780ca
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
98 изменённых файлов: 2107 добавлений и 727 удалений

4
.github/workflows/build.yml поставляемый
Просмотреть файл

@ -6,7 +6,7 @@ on:
push:
branches: [ master ]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
@ -33,7 +33,7 @@ jobs:
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Run the Maven verify phase
run: mvn --batch-mode --update-snapshots verify
run: mvn --batch-mode --update-snapshots formatter:validate verify
env:
DM_CONNECTION_STRING: https://ingest-sdkse2etest.eastus.kusto.windows.net
ENGINE_CONNECTION_STRING: https://sdkse2etest.eastus.kusto.windows.net

Просмотреть файл

@ -75,3 +75,12 @@ provided by the bot. You will only need to do this once across all repos using o
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Formatting
The code in this project is formatted using formatter-maven-plugin.
Code that isn't formatted will not be accepted.
To format your code, run the following command:
`mvn formatter:format`
It is also recommended importing the format file `kusto-style.xml` into your editor (the file is in the eclipse xml format).

Просмотреть файл

@ -18,4 +18,4 @@ public interface Client {
String executeToJsonResult(String database, String command) throws DataServiceException, DataClientException;
String executeToJsonResult(String database, String command, ClientRequestProperties properties) throws DataServiceException, DataClientException;
}
}

Просмотреть файл

@ -43,10 +43,10 @@ public class ClientImpl implements Client, StreamingClient {
private final CloseableHttpClient httpClient;
public ClientImpl(ConnectionStringBuilder csb) throws URISyntaxException {
this(csb, HttpClientProperties.builder().build());
this(csb, HttpClientProperties.builder().build());
}
public ClientImpl(ConnectionStringBuilder csb, HttpClientProperties properties) throws URISyntaxException {
public ClientImpl(ConnectionStringBuilder csb, HttpClientProperties properties) throws URISyntaxException {
this(csb, HttpClientFactory.getInstance().create(properties));
}
@ -56,12 +56,14 @@ public class ClientImpl implements Client, StreamingClient {
Objects.requireNonNull(clusterUrlForParsing.getAuthority(), "clusterUri.authority");
String auth = clusterUrlForParsing.getAuthority().toLowerCase();
if (host == null && auth.endsWith(FEDERATED_SECURITY_SUFFIX)) {
csb.setClusterUrl(new URIBuilder().setScheme(clusterUrlForParsing.getScheme()).setHost(auth.substring(0, clusterUrlForParsing.getAuthority().indexOf(FEDERATED_SECURITY_SUFFIX))).toString());
csb.setClusterUrl(
new URIBuilder().setScheme(clusterUrlForParsing.getScheme())
.setHost(auth.substring(0, clusterUrlForParsing.getAuthority().indexOf(FEDERATED_SECURITY_SUFFIX)))
.toString());
}
clusterUrl = csb.getClusterUrl();
aadAuthenticationHelper = clusterUrl.toLowerCase().startsWith(CloudInfo.LOCALHOST) ?
null : TokenProviderFactory.createTokenProvider(csb);
aadAuthenticationHelper = clusterUrl.toLowerCase().startsWith(CloudInfo.LOCALHOST) ? null : TokenProviderFactory.createTokenProvider(csb);
clientVersionForTracing = "Kusto.Java.Client";
String version = Utils.getPackageVersion();
if (StringUtils.isNotBlank(version)) {
@ -94,9 +96,12 @@ public class ClientImpl implements Client, StreamingClient {
try {
return new KustoOperationResult(response, clusterEndpoint.endsWith("v2/rest/query") ? "v2" : "v1");
} catch (KustoServiceQueryError e) {
throw new DataServiceException(clusterEndpoint,
"Error found while parsing json response as KustoOperationResult:" + e.getMessage(), e, e.isPermanent());
} catch (Exception e){
throw new DataServiceException(
clusterEndpoint,
"Error found while parsing json response as KustoOperationResult:" + e.getMessage(),
e,
e.isPermanent());
} catch (Exception e) {
throw new DataClientException(clusterEndpoint, e.getMessage(), e);
}
}
@ -125,7 +130,9 @@ public class ClientImpl implements Client, StreamingClient {
long timeoutMs = determineTimeout(properties, commandType);
String clusterEndpoint = String.format(commandType.getEndpoint(), clusterUrl);
Map<String, String> headers = generateIngestAndCommandHeaders(properties, "KJC.execute",
Map<String, String> headers = generateIngestAndCommandHeaders(
properties,
"KJC.execute",
commandType.getActivityTypeSuffix());
addCommandHeaders(headers);
String jsonPayload = generateCommandPayload(database, command, properties, clusterEndpoint);
@ -134,7 +141,14 @@ public class ClientImpl implements Client, StreamingClient {
}
@Override
public KustoOperationResult executeStreamingIngest(String database, String table, InputStream stream, ClientRequestProperties properties, String streamFormat, String mappingName, boolean leaveOpen) throws DataServiceException, DataClientException {
public KustoOperationResult executeStreamingIngest(
String database,
String table,
InputStream stream,
ClientRequestProperties properties,
String streamFormat,
String mappingName,
boolean leaveOpen) throws DataServiceException, DataClientException {
if (stream == null) {
throw new IllegalArgumentException("The provided stream is null.");
}
@ -152,7 +166,9 @@ public class ClientImpl implements Client, StreamingClient {
if (!StringUtils.isEmpty(mappingName)) {
clusterEndpoint = clusterEndpoint.concat(String.format("&mappingName=%s", mappingName));
}
Map<String, String> headers = generateIngestAndCommandHeaders(properties, "KJC.executeStreamingIngest",
Map<String, String> headers = generateIngestAndCommandHeaders(
properties,
"KJC.executeStreamingIngest",
CommandType.STREAMING_INGEST.getActivityTypeSuffix());
Long timeoutMs = null;
@ -189,7 +205,10 @@ public class ClientImpl implements Client, StreamingClient {
}
@Override
public InputStream executeStreamingQuery(String database, String command, ClientRequestProperties properties) throws DataServiceException, DataClientException {
public InputStream executeStreamingQuery(
String database,
String command,
ClientRequestProperties properties) throws DataServiceException, DataClientException {
if (StringUtils.isEmpty(database)) {
throw new IllegalArgumentException("Database is empty");
}
@ -201,12 +220,14 @@ public class ClientImpl implements Client, StreamingClient {
long timeoutMs = determineTimeout(properties, commandType);
String clusterEndpoint = String.format(commandType.getEndpoint(), clusterUrl);
Map<String, String> headers = generateIngestAndCommandHeaders(properties, "KJC.executeStreaming",
Map<String, String> headers = generateIngestAndCommandHeaders(
properties,
"KJC.executeStreaming",
commandType.getActivityTypeSuffix());
addCommandHeaders(headers);
String jsonPayload = generateCommandPayload(database, command, properties, clusterEndpoint);
return Utils.postToStreamingOutput(httpClient, clusterEndpoint, jsonPayload,timeoutMs + CLIENT_SERVER_DELTA_IN_MILLISECS, headers);
return Utils.postToStreamingOutput(httpClient, clusterEndpoint, jsonPayload, timeoutMs + CLIENT_SERVER_DELTA_IN_MILLISECS, headers);
}
private long determineTimeout(ClientRequestProperties properties, CommandType commandType) {
@ -228,10 +249,10 @@ public class ClientImpl implements Client, StreamingClient {
return CommandType.QUERY;
}
private Map<String, String> generateIngestAndCommandHeaders(ClientRequestProperties properties,
String clientRequestIdPrefix,
String activityTypeSuffix)
throws DataServiceException, DataClientException {
private Map<String, String> generateIngestAndCommandHeaders(
ClientRequestProperties properties,
String clientRequestIdPrefix,
String activityTypeSuffix) throws DataServiceException, DataClientException {
Map<String, String> headers = new HashMap<>();
headers.put("x-ms-client-version", clientVersionForTracing);
if (applicationNameForTracing != null) {
@ -252,13 +273,24 @@ public class ClientImpl implements Client, StreamingClient {
headers.put("x-ms-client-request-id", clientRequestId);
UUID activityId = UUID.randomUUID();
String activityContext = String.format("%s%s/%s, ActivityId=%s, ParentId=%s, ClientRequestId=%s", JAVA_INGEST_ACTIVITY_TYPE_PREFIX, activityTypeSuffix, activityId, activityId, activityId, clientRequestId);
String activityContext = String.format(
"%s%s/%s, ActivityId=%s, ParentId=%s, ClientRequestId=%s",
JAVA_INGEST_ACTIVITY_TYPE_PREFIX,
activityTypeSuffix,
activityId,
activityId,
activityId,
clientRequestId);
headers.put("x-ms-activitycontext", activityContext);
return headers;
}
private String generateCommandPayload(String database, String command, ClientRequestProperties properties, String clusterEndpoint) throws DataClientException {
private String generateCommandPayload(
String database,
String command,
ClientRequestProperties properties,
String clusterEndpoint) throws DataClientException {
String jsonPayload;
try {
JSONObject json = new JSONObject()
@ -271,7 +303,10 @@ public class ClientImpl implements Client, StreamingClient {
jsonPayload = json.toString();
} catch (JSONException e) {
throw new DataClientException(clusterEndpoint, String.format(clusterEndpoint, "Error executing command '%s' in database '%s'. Setting up request payload failed.", command, database), e);
throw new DataClientException(
clusterEndpoint,
String.format(clusterEndpoint, "Error executing command '%s' in database '%s'. Setting up request payload failed.", command, database),
e);
}
return jsonPayload;

Просмотреть файл

@ -38,15 +38,13 @@ public class ClientRequestProperties {
public static final String OPTION_SERVER_TIMEOUT = "servertimeout";
public static final String OPTION_CLIENT_REQUEST_ID = "ClientRequestId";
/*
* Matches valid Kusto Timespans: Optionally negative, optional number of days followed by a period, optionally up
* to 24 as hours followed by a colon, followed by up to 59 minutes (required), followed by up to 59 seconds (required),
* followed by optional subseconds prepended by a period.
* For example: 3.20:40:22 representing 3 days, 30 hours, 40 minutes and 22 seconds
* or -33:21.4551 representing -33 minutes, 21 seconds, and 4551 1/10000ths of a second
* Matches valid Kusto Timespans: Optionally negative, optional number of days followed by a period, optionally up to 24 as hours followed by a colon,
* followed by up to 59 minutes (required), followed by up to 59 seconds (required), followed by optional subseconds prepended by a period. For example:
* 3.20:40:22 representing 3 days, 30 hours, 40 minutes and 22 seconds or -33:21.4551 representing -33 minutes, 21 seconds, and 4551 1/10000ths of a second
*/
public static final Pattern KUSTO_TIMESPAN_REGEX =
Pattern.compile("(-?)(?:(\\d+)(\\.))?(?:([0-2]?\\d)(:))?([0-5]?\\d)(:)([0-5]?\\d)(?:(\\.)(\\d+))?",
Pattern.CASE_INSENSITIVE);
public static final Pattern KUSTO_TIMESPAN_REGEX = Pattern.compile(
"(-?)(?:(\\d+)(\\.))?(?:([0-2]?\\d)(:))?([0-5]?\\d)(:)([0-5]?\\d)(?:(\\.)(\\d+))?",
Pattern.CASE_INSENSITIVE);
private static final String OPTIONS_KEY = "Options";
private static final String PARAMETERS_KEY = "Parameters";
private final Map<String, Object> parameters;

Просмотреть файл

@ -71,4 +71,4 @@ public class CloseParentResourcesStream extends InputStream {
public boolean markSupported() {
return innerStream.markSupported();
}
}
}

Просмотреть файл

@ -37,14 +37,14 @@ public class Ensure {
fileExists(file, filePath);
}
public static void isTrue(boolean condition, String message){
if (!condition){
public static void isTrue(boolean condition, String message) {
if (!condition) {
throw new IllegalArgumentException("Condition evaluated to false: " + message);
}
}
public static void isFalse(boolean condition, String message){
if (condition){
public static void isFalse(boolean condition, String message) {
if (condition) {
throw new IllegalArgumentException("Condition evaluated to True: " + message);
}
}

Просмотреть файл

@ -57,8 +57,7 @@ class HttpClientFactory {
.evictIdleConnections(properties.maxIdleTime(), TimeUnit.SECONDS);
if (properties.isKeepAlive()) {
final ConnectionKeepAliveStrategy keepAliveStrategy =
new CustomConnectionKeepAliveStrategy(properties.maxKeepAliveTime());
final ConnectionKeepAliveStrategy keepAliveStrategy = new CustomConnectionKeepAliveStrategy(properties.maxKeepAliveTime());
httpClientBuilder.setKeepAliveStrategy(keepAliveStrategy);
}
@ -98,8 +97,7 @@ class HttpClientFactory {
@Override
public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
// honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator
(httpResponse.headerIterator(HTTP.CONN_KEEP_ALIVE));
HeaderElementIterator it = new BasicHeaderElementIterator(httpResponse.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();

Просмотреть файл

@ -10,11 +10,13 @@ import org.json.JSONObject;
import java.util.*;
public class KustoOperationResult implements Iterator<KustoResultSetTable> {
private static final Map<String, WellKnownDataSet> tablesKindsMap = new HashMap<String, WellKnownDataSet>() {{
put("QueryResult", WellKnownDataSet.PrimaryResult);
put("QueryProperties", WellKnownDataSet.QueryProperties);
put("QueryStatus", WellKnownDataSet.QueryCompletionInformation);
}};
private static final Map<String, WellKnownDataSet> tablesKindsMap = new HashMap<String, WellKnownDataSet>() {
{
put("QueryResult", WellKnownDataSet.PrimaryResult);
put("QueryProperties", WellKnownDataSet.QueryProperties);
put("QueryStatus", WellKnownDataSet.QueryCompletionInformation);
}
};
private static final String TABLE_NAME_PROPERTY_NAME = "Name";
private static final String TABLE_ID_PROPERTY_NAME = "Id";
private static final String TABLE_KIND_PROPERTY_NAME = "Kind";
@ -93,4 +95,4 @@ public class KustoOperationResult implements Iterator<KustoResultSetTable> {
}
}
}
}
}

Просмотреть файл

@ -23,7 +23,11 @@ class KustoResultColumnPopulator<R, C, T extends KustoType<C>> {
final boolean isNullable;
final int presetOrdinal;
static <R, C, T extends KustoType<C>> KustoResultColumnPopulator<R, C, T> of(String name, int ordinal, T type, boolean isNullable,
static <R, C, T extends KustoType<C>> KustoResultColumnPopulator<R, C, T> of(
String name,
int ordinal,
T type,
boolean isNullable,
BiConsumer<R, C> valueSetter) {
return new KustoResultColumnPopulator<>(name, ordinal, type, isNullable, valueSetter);
}
@ -61,8 +65,14 @@ class KustoResultColumnPopulator<R, C, T extends KustoType<C>> {
try {
typed = this.type.type(resultValue);
} catch (Exception e) {
throw new IllegalArgumentException(String.format("Column %s (ordinal %d) is of type %s but expected type is %s", this.name, ordinal,
resultValue.getClass().toString(), this.type.clazz.toString()), e);
throw new IllegalArgumentException(
String.format(
"Column %s (ordinal %d) is of type %s but expected type is %s",
this.name,
ordinal,
resultValue.getClass().toString(),
this.type.clazz.toString()),
e);
}
this.valueSetter.accept(objToPopulate, typed);
}

Просмотреть файл

@ -62,7 +62,7 @@ public class KustoResultSetTable {
public WellKnownDataSet getTableKind() {
return tableKind;
}
public KustoResultColumn[] getColumns() {
return columnsAsArray;
}
@ -111,8 +111,11 @@ public class KustoResultSetTable {
throw new KustoServiceQueryError(exceptions, false, EXCEPTIONS_MESSAGE);
}
} else {
throw new KustoServiceQueryError(((JSONObject) row).getJSONArray(
"OneApiErrors"), true, EXCEPTIONS_MESSAGE);
throw new KustoServiceQueryError(
((JSONObject) row).getJSONArray(
"OneApiErrors"),
true,
EXCEPTIONS_MESSAGE);
}
}
JSONArray rowAsJsonArray = jsonRows.getJSONArray(i);
@ -440,7 +443,8 @@ public class KustoResultSetTable {
public boolean last() {
if (rows.isEmpty())
return false;
while (rowIterator.next() != null) ;
while (rowIterator.next() != null)
;
return true;
}
@ -466,9 +470,13 @@ public class KustoResultSetTable {
String dateString = getString(columnIndex);
DateTimeFormatter dateTimeFormatter;
if (dateString.length() < 21) {
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ofPattern(CslDateTimeFormat.KUSTO_DATETIME_PATTERN_NO_FRACTIONS)).toFormatter();
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern(CslDateTimeFormat.KUSTO_DATETIME_PATTERN_NO_FRACTIONS))
.toFormatter();
} else {
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ofPattern(CslDateTimeFormat.KUSTO_DATETIME_PATTERN)).toFormatter();
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern(CslDateTimeFormat.KUSTO_DATETIME_PATTERN))
.toFormatter();
}
return LocalDateTime.parse(getString(columnIndex), dateTimeFormatter);
}

Просмотреть файл

@ -12,8 +12,11 @@ public class Results {
private ArrayList<ArrayList<String>> values;
private String exceptionsMessages;
public Results(HashMap<String, Integer> columnNameToIndex, HashMap<String, String> columnNameToType,
ArrayList<ArrayList<String>> values, String exceptionsMessages) {
public Results(
HashMap<String, Integer> columnNameToIndex,
HashMap<String, String> columnNameToType,
ArrayList<ArrayList<String>> values,
String exceptionsMessages) {
this.columnNameToIndex = columnNameToIndex;
this.columnNameToType = columnNameToType;
this.values = values;

Просмотреть файл

@ -26,7 +26,14 @@ public interface StreamingClient {
* @throws DataClientException An exception originating from a client activity
* @throws DataServiceException An exception returned from the service
*/
KustoOperationResult executeStreamingIngest(String database, String table, InputStream stream, ClientRequestProperties properties, String streamFormat, String mappingName, boolean leaveOpen) throws DataServiceException, DataClientException;
KustoOperationResult executeStreamingIngest(
String database,
String table,
InputStream stream,
ClientRequestProperties properties,
String streamFormat,
String mappingName,
boolean leaveOpen) throws DataServiceException, DataClientException;
/**
* <p>Query directly from Kusto database using streaming output.</p>

Просмотреть файл

@ -13,8 +13,7 @@ public class UriUtils {
if (ensureTrailingSlash && !path.endsWith("/")) {
path += "/";
}
if (!path.startsWith("/"))
{
if (!path.startsWith("/")) {
path = "/" + path;
}

Просмотреть файл

@ -56,14 +56,19 @@ class Utils {
// Hide constructor, as this is a static utility class
}
static String post(CloseableHttpClient httpClient, String urlStr, String payload, InputStream stream, long timeoutMs, Map<String, String> headers, boolean leaveOpen) throws DataServiceException, DataClientException {
static String post(
CloseableHttpClient httpClient,
String urlStr,
String payload,
InputStream stream,
long timeoutMs,
Map<String, String> headers,
boolean leaveOpen) throws DataServiceException, DataClientException {
URI url = parseUriFromUrlString(urlStr);
try (InputStream ignored = (stream != null && !leaveOpen) ? stream : null) {
HttpPost request = setupHttpPostRequest(url, payload, stream, headers);
int requestTimeout = timeoutMs > Integer.MAX_VALUE ?
Integer.MAX_VALUE :
Math.toIntExact(timeoutMs);
int requestTimeout = timeoutMs > Integer.MAX_VALUE ? Integer.MAX_VALUE : Math.toIntExact(timeoutMs);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(requestTimeout).build();
request.setConfig(requestConfig);
@ -88,22 +93,32 @@ class Utils {
return null;
}
static InputStream postToStreamingOutput(CloseableHttpClient httpClient, String url, String payload, long timeoutMs, Map<String, String> headers) throws DataServiceException, DataClientException {
static InputStream postToStreamingOutput(
CloseableHttpClient httpClient,
String url,
String payload,
long timeoutMs,
Map<String, String> headers) throws DataServiceException, DataClientException {
return postToStreamingOutput(httpClient, url, payload, timeoutMs, headers, 0);
}
static InputStream postToStreamingOutput(CloseableHttpClient httpClient, String url, String payload, long timeoutMs, Map<String, String> headers, int redirectCount) throws DataServiceException, DataClientException {
static InputStream postToStreamingOutput(
CloseableHttpClient httpClient,
String url,
String payload,
long timeoutMs,
Map<String, String> headers,
int redirectCount) throws DataServiceException, DataClientException {
long timeoutTimeMs = System.currentTimeMillis() + timeoutMs;
URI uri = parseUriFromUrlString(url);
boolean returnInputStream = false;
String errorFromResponse = null;
/*
* The caller must close the inputStream to close the following underlying resources (httpClient and httpResponse).
* We use CloseParentResourcesStream so that when the stream is closed, these resources are closed as well. We
* shouldn't need to do that, per https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/fundamentals.html:
* "In order to ensure proper release of system resources one must close either the content stream associated
* with the entity or the response itself." However, in my testing this wasn't reliably the case.
* We further use EofSensorInputStream to close the stream even if not explicitly closed, once all content is consumed.
* The caller must close the inputStream to close the following underlying resources (httpClient and httpResponse). We use CloseParentResourcesStream so
* that when the stream is closed, these resources are closed as well. We shouldn't need to do that, per
* https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/fundamentals.html: "In order to ensure proper release of system resources one
* must close either the content stream associated with the entity or the response itself." However, in my testing this wasn't reliably the case. We
* further use EofSensorInputStream to close the stream even if not explicitly closed, once all content is consumed.
*/
CloseableHttpResponse httpResponse = null;
try {
@ -130,7 +145,8 @@ class Utils {
return deflaterInputStream;
}
}
// Though the server responds with a gzip/deflate Content-Encoding header, we reach here because httpclient uses LazyDecompressingStream which handles the above logic
// Though the server responds with a gzip/deflate Content-Encoding header, we reach here because httpclient uses LazyDecompressingStream which
// handles the above logic
returnInputStream = true;
return contentStream;
}
@ -146,8 +162,11 @@ class Utils {
}
}
} catch (IOException ex) {
throw new DataServiceException(url, "postToStreamingOutput failed to get or decompress response stream",
ex, false);
throw new DataServiceException(
url,
"postToStreamingOutput failed to get or decompress response stream",
ex,
false);
} catch (Exception ex) {
throw createExceptionFromResponse(url, httpResponse, ex, errorFromResponse);
} finally {
@ -162,9 +181,9 @@ class Utils {
return new DataServiceException(url, "POST failed to send request", thrownException, false);
} else {
/*
* TODO: When we add another streaming API that returns a KustoOperationResult, we'll need to handle the 2 types of
* content errors this API can return: (1) Inline error (engine identifies error after it starts building the json
* result), or (2) in the KustoOperationResult's QueryCompletionInformation, both of which present with "200 OK". See .Net's DataReaderParser.
* TODO: When we add another streaming API that returns a KustoOperationResult, we'll need to handle the 2 types of content errors this API can
* return: (1) Inline error (engine identifies error after it starts building the json result), or (2) in the KustoOperationResult's
* QueryCompletionInformation, both of which present with "200 OK". See .Net's DataReaderParser.
*/
String activityId = determineActivityId(httpResponse);
String message = errorFromResponse;
@ -246,10 +265,19 @@ class Utils {
try {
URL cleanUrl = new URL(url);
if ("https".equalsIgnoreCase(cleanUrl.getProtocol()) || cleanUrl.getHost().equalsIgnoreCase(CloudInfo.LOCALHOST)) {
return new URI(cleanUrl.getProtocol(), cleanUrl.getUserInfo(), cleanUrl.getHost(), cleanUrl.getPort(), cleanUrl.getPath(), cleanUrl.getQuery(), cleanUrl.getRef());
return new URI(
cleanUrl.getProtocol(),
cleanUrl.getUserInfo(),
cleanUrl.getHost(),
cleanUrl.getPort(),
cleanUrl.getPath(),
cleanUrl.getQuery(),
cleanUrl.getRef());
} else {
throw new DataClientException(url, "Cannot forward security token to a remote service over insecure " +
"channel (http://)");
throw new DataClientException(
url,
"Cannot forward security token to a remote service over insecure " +
"channel (http://)");
}
} catch (URISyntaxException | MalformedURLException e) {
throw new DataClientException(url, "Error parsing target URL in post request:" + e.getMessage(), e);
@ -286,4 +314,3 @@ class Utils {
return seconds < 0 ? "-" + positive : positive;
}
}

Просмотреть файл

@ -13,7 +13,11 @@ import org.jetbrains.annotations.NotNull;
public class ApplicationCertificateTokenProvider extends ConfidentialAppTokenProviderBase {
private final IClientCertificate clientCertificate;
ApplicationCertificateTokenProvider(@NotNull String clusterUrl, @NotNull String applicationClientId, @NotNull IClientCertificate clientCertificate, String authorityId) throws URISyntaxException {
ApplicationCertificateTokenProvider(
@NotNull String clusterUrl,
@NotNull String applicationClientId,
@NotNull IClientCertificate clientCertificate,
String authorityId) throws URISyntaxException {
super(clusterUrl, applicationClientId, authorityId);
this.clientCertificate = clientCertificate;
}

Просмотреть файл

@ -13,7 +13,11 @@ import org.jetbrains.annotations.NotNull;
public class ApplicationKeyTokenProvider extends ConfidentialAppTokenProviderBase {
private final IClientSecret clientSecret;
ApplicationKeyTokenProvider(@NotNull String clusterUrl, @NotNull String applicationClientId, @NotNull IClientSecret clientSecret, String authorityId) throws URISyntaxException {
ApplicationKeyTokenProvider(
@NotNull String clusterUrl,
@NotNull String applicationClientId,
@NotNull IClientSecret clientSecret,
String authorityId) throws URISyntaxException {
super(clusterUrl, applicationClientId, authorityId);
this.clientSecret = clientSecret;
}

Просмотреть файл

@ -26,4 +26,4 @@ public class CallbackTokenProvider extends TokenProviderBase {
throw new DataClientException(clusterUrl, e.getMessage(), e);
}
}
}
}

Просмотреть файл

@ -11,8 +11,7 @@ import java.util.Set;
import org.jetbrains.annotations.NotNull;
public abstract class CloudDependentTokenProviderBase extends TokenProviderBase {
private static final String ERROR_INVALID_SERVICE_RESOURCE_URL =
"Error determining scope due to invalid Kusto Service Resource URL";
private static final String ERROR_INVALID_SERVICE_RESOURCE_URL = "Error determining scope due to invalid Kusto Service Resource URL";
protected final Set<String> scopes = new HashSet<>();
private boolean initialized = false;

Просмотреть файл

@ -30,8 +30,7 @@ public class CloudInfo {
DEFAULT_KUSTO_CLIENT_APP_ID,
DEFAULT_REDIRECT_URI,
DEFAULT_KUSTO_SERVICE_RESOURCE_ID,
DEFAULT_FIRST_PARTY_AUTHORITY_URL
);
DEFAULT_FIRST_PARTY_AUTHORITY_URL);
public static final String LOCALHOST = "http://localhost";
private static final Map<String, CloudInfo> cache = new HashMap<>();
@ -47,7 +46,13 @@ public class CloudInfo {
private final String kustoServiceResourceId;
private final String firstPartyAuthorityUrl;
public CloudInfo(boolean loginMfaRequired, String loginEndpoint, String kustoClientAppId, String kustoClientRedirectUri, String kustoServiceResourceId, String firstPartyAuthorityUrl) {
public CloudInfo(
boolean loginMfaRequired,
String loginEndpoint,
String kustoClientAppId,
String kustoClientRedirectUri,
String kustoServiceResourceId,
String firstPartyAuthorityUrl) {
this.loginMfaRequired = loginMfaRequired;
this.loginEndpoint = loginEndpoint;
this.kustoClientAppId = kustoClientAppId;
@ -92,8 +97,10 @@ public class CloudInfo {
result = DEFAULT_CLOUD;
} else {
String errorFromResponse = EntityUtils.toString(response.getEntity());
throw new DataServiceException(clusterUrl,
"Error in metadata endpoint, got code: " + statusCode + "\nWith error: " + errorFromResponse, true);
throw new DataServiceException(
clusterUrl,
"Error in metadata endpoint, got code: " + statusCode + "\nWith error: " + errorFromResponse,
true);
}
}
} catch (IOException | URISyntaxException ex) {
@ -116,8 +123,7 @@ public class CloudInfo {
innerObject.getString("KustoClientAppId"),
innerObject.getString("KustoClientRedirectUri"),
innerObject.getString("KustoServiceResourceId"),
innerObject.getString("FirstPartyAuthorityUrl")
);
innerObject.getString("FirstPartyAuthorityUrl"));
}
@Override

Просмотреть файл

@ -58,8 +58,7 @@ public abstract class ConfidentialAppTokenProviderBase extends MsalTokenProvider
}
@Override
protected IAuthenticationResult acquireAccessTokenSilentlyMsal()
throws MalformedURLException, InterruptedException, ExecutionException, TimeoutException {
protected IAuthenticationResult acquireAccessTokenSilentlyMsal() throws MalformedURLException, InterruptedException, ExecutionException, TimeoutException {
CompletableFuture<Set<IAccount>> accounts = clientApplication.getAccounts();
return clientApplication
.acquireTokenSilently(getSilentParameters(accounts.join()))

Просмотреть файл

@ -54,7 +54,7 @@ public class ConnectionStringBuilder {
this.applicationNameForTracing = null;
}
public ConnectionStringBuilder(ConnectionStringBuilder other){
public ConnectionStringBuilder(ConnectionStringBuilder other) {
this.clusterUrl = other.clusterUrl;
this.usernameHint = other.usernameHint;
this.applicationClientId = other.applicationClientId;
@ -74,7 +74,6 @@ public class ConnectionStringBuilder {
this.applicationNameForTracing = other.applicationNameForTracing;
}
public String getClusterUrl() {
return clusterUrl;
}
@ -119,7 +118,7 @@ public class ConnectionStringBuilder {
return tokenProvider;
}
public String getManagedIdentityClientId () {
public String getManagedIdentityClientId() {
return managedIdentityClientId;
}
@ -155,17 +154,18 @@ public class ConnectionStringBuilder {
this.applicationNameForTracing = applicationNameForTracing;
}
public static ConnectionStringBuilder createWithAadApplicationCredentials(String clusterUrl,
String applicationClientId,
String applicationKey) {
public static ConnectionStringBuilder createWithAadApplicationCredentials(
String clusterUrl,
String applicationClientId,
String applicationKey) {
return createWithAadApplicationCredentials(clusterUrl, applicationClientId, applicationKey, null);
}
public static ConnectionStringBuilder createWithAadApplicationCredentials(String clusterUrl,
String applicationClientId,
String applicationKey,
String authorityId) {
public static ConnectionStringBuilder createWithAadApplicationCredentials(
String clusterUrl,
String applicationClientId,
String applicationKey,
String authorityId) {
if (StringUtils.isEmpty(clusterUrl)) {
throw new IllegalArgumentException("clusterUrl cannot be null or empty");
}
@ -218,18 +218,20 @@ public class ConnectionStringBuilder {
return csb;
}
public static ConnectionStringBuilder createWithAadApplicationCertificate(String clusterUrl,
String applicationClientId,
X509Certificate x509Certificate,
PrivateKey privateKey) {
public static ConnectionStringBuilder createWithAadApplicationCertificate(
String clusterUrl,
String applicationClientId,
X509Certificate x509Certificate,
PrivateKey privateKey) {
return createWithAadApplicationCertificate(clusterUrl, applicationClientId, x509Certificate, privateKey, null);
}
public static ConnectionStringBuilder createWithAadApplicationCertificate(String clusterUrl,
String applicationClientId,
X509Certificate x509Certificate,
PrivateKey privateKey,
String authorityId) {
public static ConnectionStringBuilder createWithAadApplicationCertificate(
String clusterUrl,
String applicationClientId,
X509Certificate x509Certificate,
PrivateKey privateKey,
String authorityId) {
if (StringUtils.isEmpty(clusterUrl)) {
throw new IllegalArgumentException("clusterUrl cannot be null or empty");
}
@ -251,18 +253,20 @@ public class ConnectionStringBuilder {
return csb;
}
public static ConnectionStringBuilder createWithAadApplicationCertificateSubjectNameIssuer(String clusterUrl,
String applicationClientId,
List<X509Certificate> x509CertificateChain,
PrivateKey privateKey) {
public static ConnectionStringBuilder createWithAadApplicationCertificateSubjectNameIssuer(
String clusterUrl,
String applicationClientId,
List<X509Certificate> x509CertificateChain,
PrivateKey privateKey) {
return createWithAadApplicationCertificateSubjectNameIssuer(clusterUrl, applicationClientId, x509CertificateChain, privateKey, null);
}
public static ConnectionStringBuilder createWithAadApplicationCertificateSubjectNameIssuer(String clusterUrl,
String applicationClientId,
List<X509Certificate> x509CertificateChain,
PrivateKey privateKey,
String authorityId) {
public static ConnectionStringBuilder createWithAadApplicationCertificateSubjectNameIssuer(
String clusterUrl,
String applicationClientId,
List<X509Certificate> x509CertificateChain,
PrivateKey privateKey,
String authorityId) {
if (StringUtils.isEmpty(clusterUrl)) {
throw new IllegalArgumentException("clusterUrl cannot be null or empty");
}
@ -325,4 +329,4 @@ public class ConnectionStringBuilder {
csb.useManagedIdentityAuth = true;
return csb;
}
}
}

Просмотреть файл

@ -18,7 +18,7 @@ public class DeviceAuthTokenProvider extends PublicAppTokenProviderBase {
System.out.println(deviceCode.message());
};
DeviceCodeFlowParameters deviceCodeFlowParams = DeviceCodeFlowParameters.builder(scopes,deviceCodeConsumer).build();
DeviceCodeFlowParameters deviceCodeFlowParams = DeviceCodeFlowParameters.builder(scopes, deviceCodeConsumer).build();
return clientApplication.acquireToken(deviceCodeFlowParams).join();
}
}
}

Просмотреть файл

@ -47,7 +47,6 @@ public abstract class MsalTokenProviderBase extends CloudDependentTokenProviderB
}
}
@Override
public String acquireAccessTokenImpl() throws DataServiceException, DataClientException {
IAuthenticationResult accessTokenResult = acquireAccessTokenSilently();

Просмотреть файл

@ -25,7 +25,6 @@ public abstract class PublicAppTokenProviderBase extends MsalTokenProviderBase {
super(clusterUrl, authorityId);
}
@Override
protected void initializeWithCloudInfo(CloudInfo cloudInfo) throws DataClientException, DataServiceException {
super.initializeWithCloudInfo(cloudInfo);

Просмотреть файл

@ -10,7 +10,11 @@ import org.jetbrains.annotations.NotNull;
public class SubjectNameIssuerTokenProvider extends ConfidentialAppTokenProviderBase {
private final IClientCertificate clientCertificate;
SubjectNameIssuerTokenProvider(@NotNull String clusterUrl, @NotNull String applicationClientId, @NotNull IClientCertificate clientCertificate, String authorityId) throws URISyntaxException {
SubjectNameIssuerTokenProvider(
@NotNull String clusterUrl,
@NotNull String applicationClientId,
@NotNull IClientCertificate clientCertificate,
String authorityId) throws URISyntaxException {
super(clusterUrl, applicationClientId, authorityId);
this.clientCertificate = clientCertificate;
}

Просмотреть файл

@ -42,7 +42,7 @@ public class TokenProviderFactory {
} else if (csb.getTokenProvider() != null) {
Callable<String> tokenProvider = csb.getTokenProvider();
return new CallbackTokenProvider(clusterUrl, tokenProvider);
} else if(csb.isUseDeviceCodeAuth()) {
} else if (csb.isUseDeviceCodeAuth()) {
return new DeviceAuthTokenProvider(clusterUrl, authorityId);
} else if (csb.isUseManagedIdentityAuth()) {
return new ManagedIdentityTokenProvider(clusterUrl, csb.getManagedIdentityClientId());
@ -56,4 +56,4 @@ public class TokenProviderFactory {
throw new IllegalArgumentException("No token provider exists for the provided ConnectionStringBuilder");
}
}
}
}

Просмотреть файл

@ -52,8 +52,8 @@ public class UserPromptTokenProvider extends PublicAppTokenProviderBase {
try {
// This is the only auth method that allows the same application to be used for multiple distinct accounts, so reset account cache between sign-ins
clientApplication = PublicClientApplication.builder(clientAppId).authority(aadAuthorityUrl).build();
CompletableFuture<IAuthenticationResult> future =
clientApplication.acquireToken(InteractiveRequestParameters.builder(redirectUri).scopes(scopes).loginHint(usernameHint).build());
CompletableFuture<IAuthenticationResult> future = clientApplication
.acquireToken(InteractiveRequestParameters.builder(redirectUri).scopes(scopes).loginHint(usernameHint).build());
result = future.get(USER_PROMPT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (MalformedURLException e) {
throw new DataClientException(clusterUrl, ERROR_INVALID_AUTHORITY_URL, e);
@ -64,7 +64,9 @@ public class UserPromptTokenProvider extends PublicAppTokenProviderBase {
throw new DataServiceException(clusterUrl, ERROR_ACQUIRING_APPLICATION_ACCESS_TOKEN, e, false);
}
if (result == null) {
throw new DataServiceException(clusterUrl, "acquireWithUserPrompt got 'null' authentication result",
throw new DataServiceException(
clusterUrl,
"acquireWithUserPrompt got 'null' authentication result",
false);
}
return result;

Просмотреть файл

@ -8,6 +8,7 @@ import org.json.JSONException;
import java.util.ArrayList;
import java.util.List;
/*
This class represents an error that returned from the query result
*/

Просмотреть файл

@ -22,8 +22,7 @@ public class OneApiError {
jsonObject.getString("@message"),
jsonObject.getString("@type"),
jsonObject.getJSONObject("@context"),
jsonObject.getBoolean("@permanent")
);
jsonObject.getBoolean("@permanent"));
}
private final String code;

Просмотреть файл

@ -4,8 +4,7 @@ import org.apache.http.HttpResponse;
import org.jetbrains.annotations.Nullable;
public class WebException extends Exception {
@Nullable
protected final HttpResponse httpResponse;
@Nullable protected final HttpResponse httpResponse;
public WebException(String message, @Nullable HttpResponse httpResponse, Throwable cause) {
super(message, cause);

Просмотреть файл

@ -25,4 +25,4 @@ public class CslBoolFormat extends CslFormat {
return Boolean.TRUE.equals(value) ? "true" : "false";
}
}
}

Просмотреть файл

@ -19,22 +19,23 @@ public class CslDateTimeFormat extends CslFormat {
public static final String KUSTO_DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'";
public static final String KUSTO_DATETIME_PATTERN_NO_FRACTIONS = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(KUSTO_DATETIME_PATTERN).withZone(ZoneId.of("UTC"));
Map<Integer, String> KUSTO_DATETIME_FORMATS = Stream.of(new Object[][] {
{ 4, "yyyy" },
{ 6, "yyyyMM" },
{ 8, "yyyyMMdd" },
{ 10, "yyyyMMddHH" },
{ 12, "yyyyMMddHHmm" },
{ 14, "yyyyMMddHHmmss" },
{ 17, "yyyyMMdd HH:mm:ss" },
{ 19, "yyyyMMdd HH:mm:ss.f" },
{ 20, "yyyyMMdd HH:mm:ss.ff" },
{ 21, "yyyyMMdd HH:mm:ss.fff" },
{ 22, "yyyyMMdd HH:mm:ss.ffff" },
{ 23, "yyyyMMdd HH:mm:ss.fffff" },
{ 24, "yyyyMMdd HH:mm:ss.ffffff" },
{ 25, "yyyyMMdd HH:mm:ss.fffffff" }
}).collect(Collectors.toMap(data -> (Integer) data[0], data -> (String) data[1]));
Map<Integer, String> KUSTO_DATETIME_FORMATS = Stream.of(
new Object[][] {
{4, "yyyy"},
{6, "yyyyMM"},
{8, "yyyyMMdd"},
{10, "yyyyMMddHH"},
{12, "yyyyMMddHHmm"},
{14, "yyyyMMddHHmmss"},
{17, "yyyyMMdd HH:mm:ss"},
{19, "yyyyMMdd HH:mm:ss.f"},
{20, "yyyyMMdd HH:mm:ss.ff"},
{21, "yyyyMMdd HH:mm:ss.fff"},
{22, "yyyyMMdd HH:mm:ss.ffff"},
{23, "yyyyMMdd HH:mm:ss.fffff"},
{24, "yyyyMMdd HH:mm:ss.ffffff"},
{25, "yyyyMMdd HH:mm:ss.fffffff"}
}).collect(Collectors.toMap(data -> (Integer) data[0], data -> (String) data[1]));
private final LocalDateTime value;
@ -122,13 +123,17 @@ public class CslDateTimeFormat extends CslFormat {
// Old Java SDK approach to parsing, using particular mask
try {
if (localDateTimeString.length() < 21) {
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ofPattern(KUSTO_DATETIME_PATTERN_NO_FRACTIONS)).toFormatter();
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern(KUSTO_DATETIME_PATTERN_NO_FRACTIONS))
.toFormatter();
} else {
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ofPattern(KUSTO_DATETIME_PATTERN)).toFormatter();
dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern(KUSTO_DATETIME_PATTERN))
.toFormatter();
}
return LocalDateTime.parse(localDateTimeString, dateTimeFormatter);
} catch (Exception e) {
return null;
}
}
}
}

Просмотреть файл

@ -25,4 +25,4 @@ public class CslIntFormat extends CslFormat {
return Integer.toString(value);
}
}
}

Просмотреть файл

@ -25,4 +25,4 @@ public class CslLongFormat extends CslFormat {
return Long.toString(value);
}
}
}

Просмотреть файл

@ -25,4 +25,4 @@ public class CslRealFormat extends CslFormat {
return Double.toString(value);
}
}
}

Просмотреть файл

@ -84,4 +84,4 @@ public class CslStringFormat extends CslFormat {
return escapedString;
}
}
}

Просмотреть файл

@ -78,4 +78,4 @@ public class CslTimespanFormat extends CslFormat {
return result;
}
}
}

Просмотреть файл

@ -27,4 +27,4 @@ public class CslUuidFormat extends CslFormat {
return value.toString();
}
}
}

Просмотреть файл

@ -200,4 +200,4 @@ class ClientRequestPropertiesTest {
String result = new CslTimespanFormat(timeString).toString();
Assertions.assertEquals("time(" + timeString + ")", result);
}
}
}

Просмотреть файл

@ -24,25 +24,31 @@ class ConnectionStringBuilderTest {
@DisplayName("validate createWithAadApplicationCredentials throws IllegalArgumentException exception when missing or invalid parameters")
void createWithAadApplicationCredentials() {
//nullOrEmpty appId
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty appId
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials("resource.uri", null, "appKey"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials("resource.uri", "", "appKey"));
//nullOrEmpty appKey
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty appKey
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials("resource.uri", "appId", null));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials("resource.uri", "appId", ""));
//nullOrEmpty resourceUri
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty resourceUri
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials(null, "appId", "appKey"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCredentials("", "appId", "appKey"));
}
@ -50,19 +56,20 @@ class ConnectionStringBuilderTest {
@Test
@DisplayName("validate createWithUserPrompt throws IllegalArgumentException exception when missing or invalid parameters")
void createWithUserPrompt() {
//nullOrEmpty resourceUri
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty resourceUri
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithUserPrompt(null, null));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithUserPrompt("", ""));
}
@Test
@DisplayName("validate createWithAadApplicationCertificate throws IllegalArgumentException exception when missing or invalid parameters")
void createWithAadApplicationCertificate() throws CertificateException, OperatorCreationException,
PKCSException, IOException {
void createWithAadApplicationCertificate() throws CertificateException, OperatorCreationException, PKCSException, IOException {
String certFilePath = Paths.get("src", "test", "resources", "cert.cer").toString();
String privateKeyPath = Paths.get("src", "test", "resources", "key.pem").toString();
@ -70,27 +77,33 @@ class ConnectionStringBuilderTest {
X509Certificate x509Certificate = readPem(certFilePath, "basic").getCertificate();
PrivateKey privateKey = readPem(privateKeyPath, "basic").getKey();
//nullOrEmpty resourceUri
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty resourceUri
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate(null, "appId", x509Certificate, privateKey));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate("", "appId", x509Certificate, privateKey));
//nullOrEmpty appId
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty appId
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate("resource.uri", null, x509Certificate, privateKey));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate("resource.uri", "", x509Certificate, privateKey));
//null certificate
Assertions.assertThrows(IllegalArgumentException.class,
// null certificate
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate("resource.uri", "appID", null, privateKey));
//null privateKey
Assertions.assertThrows(IllegalArgumentException.class,
// null privateKey
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadApplicationCertificate("resource.uri", "appID", x509Certificate, null));
}
@ -99,37 +112,46 @@ class ConnectionStringBuilderTest {
@DisplayName("validate createWithAadAccessTokenAuthentication throws IllegalArgumentException exception when missing or invalid parameters")
void createWithAadAccessTokenAuthentication() {
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication(null, "token"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication("", "token"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication("resource.uri", null));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication("resource.uri", ""));
Assertions.assertDoesNotThrow(() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication("resource.uri", "token"));
Assertions.assertDoesNotThrow(
() -> ConnectionStringBuilder
.createWithAadAccessTokenAuthentication("resource.uri", "token"));
}
@Test
@DisplayName("validate createWithAadTokenProviderAuthentication throws IllegalArgumentException exception when missing or invalid parameters")
void createWithAadTokenProviderAuthentication() {
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadTokenProviderAuthentication(null, () -> "token"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadTokenProviderAuthentication("", () -> "token"));
Assertions.assertThrows(IllegalArgumentException.class,
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithAadTokenProviderAuthentication("resource.uri", null));
Assertions.assertDoesNotThrow(() -> ConnectionStringBuilder
.createWithAadTokenProviderAuthentication("resource.uri", () -> "token"));
Assertions.assertDoesNotThrow(
() -> ConnectionStringBuilder
.createWithAadTokenProviderAuthentication("resource.uri", () -> "token"));
}
@Test
@ -151,11 +173,13 @@ class ConnectionStringBuilderTest {
@Test
@DisplayName("validate createWithDeviceAuthentication throws IllegalArgumentException exception when missing or invalid parameters")
void createWithDeviceAuthentication() {
//nullOrEmpty resourceUri
Assertions.assertThrows(IllegalArgumentException.class,
// nullOrEmpty resourceUri
Assertions.assertThrows(
IllegalArgumentException.class,
() -> ConnectionStringBuilder
.createWithDeviceCode(null, null));
Assertions.assertDoesNotThrow(() -> ConnectionStringBuilder
.createWithDeviceCode("resource.uri"));
Assertions.assertDoesNotThrow(
() -> ConnectionStringBuilder
.createWithDeviceCode("resource.uri"));
}
}
}

Просмотреть файл

@ -7,19 +7,19 @@ import org.junit.jupiter.api.Test;
class HttpClientFactoryTest {
final HttpClientFactory httpClientFactory = HttpClientFactory.getInstance();
final HttpClientFactory httpClientFactory = HttpClientFactory.getInstance();
@Test
@DisplayName("test create http client from null properties")
void testNullProperties() {
Assertions.assertDoesNotThrow(() -> httpClientFactory.create(null));
}
@Test
@DisplayName("test create http client from null properties")
void testNullProperties() {
Assertions.assertDoesNotThrow(() -> httpClientFactory.create(null));
}
@Test
@DisplayName("test create http client from properties")
void testProperties() {
HttpClientProperties properties = HttpClientProperties.builder().build();
final CloseableHttpClient httpClient = httpClientFactory.create(properties);
Assertions.assertNotNull(httpClient);
}
@Test
@DisplayName("test create http client from properties")
void testProperties() {
HttpClientProperties properties = HttpClientProperties.builder().build();
final CloseableHttpClient httpClient = httpClientFactory.create(properties);
Assertions.assertNotNull(httpClient);
}
}

Просмотреть файл

@ -60,7 +60,8 @@ public class KustoResultMapperTest {
.addColumn(KustoType.DATETIME_ZONED_DATE_TIME, "TimeColumn", true, TestPojo::setZonedTime)
.addColumn(KustoType.GUID_UUID, "Guid", true, TestPojo::setUuid)
.addColumn(KustoType.STRING, "Enum", true, (r, t) -> r.setTestEnum(t != null ? TestEnum.valueOf(t) : null))
.addColumn(KustoType.DATETIME_INSTANT, "Instant", true, TestPojo::setInstantTime).build();
.addColumn(KustoType.DATETIME_INSTANT, "Instant", true, TestPojo::setInstantTime)
.build();
static final KustoResultMapper<TestPojo> ordinalMapper = KustoResultMapper.newBuilder(TestPojo::new)
.addColumn(KustoType.INTEGER, 1, false, TestPojo::setId)
@ -68,7 +69,8 @@ public class KustoResultMapperTest {
.addColumn(KustoType.DATETIME_ZONED_DATE_TIME, 3, true, TestPojo::setZonedTime)
.addColumn(KustoType.GUID_UUID, 4, true, TestPojo::setUuid)
.addColumn(KustoType.STRING, "Enum", true, (r, t) -> r.setTestEnum(t != null ? TestEnum.valueOf(t) : null))
.addColumn(KustoType.DATETIME_INSTANT, 6, true, TestPojo::setInstantTime).build();
.addColumn(KustoType.DATETIME_INSTANT, 6, true, TestPojo::setInstantTime)
.build();
static final KustoResultMapper<TestPojo> mixedMapper = KustoResultMapper.newBuilder(TestPojo::new)
.addColumn(KustoType.INTEGER, "Id", 1, false, TestPojo::setId)
@ -76,7 +78,8 @@ public class KustoResultMapperTest {
.addColumn(KustoType.DATETIME_ZONED_DATE_TIME, "TimeColumn", 3, true, TestPojo::setZonedTime)
.addColumn(KustoType.GUID_UUID, "Guid", 4, true, TestPojo::setUuid)
.addColumn(KustoType.STRING, "Enum", 5, true, (r, t) -> r.setTestEnum(t != null ? TestEnum.valueOf(t) : null))
.addColumn(KustoType.DATETIME_INSTANT, "Instant", 6, true, TestPojo::setInstantTime).build();
.addColumn(KustoType.DATETIME_INSTANT, "Instant", 6, true, TestPojo::setInstantTime)
.build();
KustoResultSetTable resultSet = mock(KustoResultSetTable.class);

Просмотреть файл

@ -68,9 +68,11 @@ public class ResultSetTest {
"\"ColumnName\": \"g\", \"ColumnType\": \"int\" }, { \"ColumnName\": \"h\", \"ColumnType\": " +
"\"long\" }, { \"ColumnName\": \"i\", \"ColumnType\": \"real\" }, { \"ColumnName\": \"j\", " +
"\"ColumnType\": \"timespan\" },{ \"ColumnName\": \"k\", \"ColumnType\": \"short\" } ]";
KustoResultSetTable res = new KustoResultSetTable(new JSONObject("{\"TableName\":\"Table_0\"," +
"\"Columns\":" + columns + ",\"Rows\":" +
rows.toString() + "}"));
KustoResultSetTable res = new KustoResultSetTable(
new JSONObject(
"{\"TableName\":\"Table_0\"," +
"\"Columns\":" + columns + ",\"Rows\":" +
rows.toString() + "}"));
res.next();
assert res.getBooleanObject(0) == null;
assert res.getString(1).equals("");
@ -103,4 +105,4 @@ public class ResultSetTest {
Assertions.assertEquals(res.getLocalTime(9), LocalTime.parse(durationAsKustoString));
Assertions.assertEquals(res.getShort(10), s1);
}
}
}

Просмотреть файл

@ -55,7 +55,7 @@ class UncloseableStreamTest {
void WhenSkipThenClose_ThenInnerStreamIsNotClosed() throws IOException {
int amount = 3;
int skipped = (int)stream.skip(amount);
int skipped = (int) stream.skip(amount);
assertEquals(amount, skipped);
stream.close();
@ -147,7 +147,6 @@ class UncloseableStreamTest {
verify(stream.getInnerStream(), never()).close();
}
@Test
void TestMarkSupported_MatchesInnerMarkSupported() throws IOException {
assertEquals(stream.markSupported(), stream.getInnerStream().markSupported());
@ -157,4 +156,4 @@ class UncloseableStreamTest {
verify(stream.getInnerStream(), times(4)).markSupported();
verify(stream.getInnerStream(), never()).close();
}
}
}

Просмотреть файл

@ -33,14 +33,14 @@ class UtilitiesTest {
// If set to over MAX_TIMEOUT_MS - value should be MAX_TIMEOUT_MS
clientRequestProperties.setOption(ClientRequestProperties.OPTION_SERVER_TIMEOUT, "1.01:40:02.1");
Assertions.assertEquals(ClientRequestProperties.MAX_TIMEOUT_MS,
Assertions.assertEquals(
ClientRequestProperties.MAX_TIMEOUT_MS,
clientRequestProperties.getTimeoutInMilliSec());
clientRequestProperties.setOption(ClientRequestProperties.OPTION_SERVER_TIMEOUT, "15:00");
Assertions.assertEquals(TimeUnit.HOURS.toMillis(15), clientRequestProperties.getTimeoutInMilliSec());
}
@Test
@DisplayName("Test exception creation when the web response is null")
void createExceptionFromResponseNoResponse() {
@ -77,7 +77,8 @@ class UtilitiesTest {
" \"subActivityId\": \"a57ec272-8846-49e6-b458-460b841ed47d\",\n" +
" \"activityType\": \"PO-OWIN-CallContext\",\n" +
" \"parentActivityId\": \"a57ec272-8846-49e6-b458-460b841ed47d\",\n" +
" \"activityStack\": \"(Activity stack: CRID=KPC.execute;d3a43e37-0d7f-47a9-b6cd-a889b2aee3d3 ARID=a57ec272-8846-49e6-b458-460b841ed47d > PO-OWIN-CallContext/a57ec272-8846-49e6-b458-460b841ed47d)\"\n" +
" \"activityStack\": \"(Activity stack: CRID=KPC.execute;d3a43e37-0d7f-47a9-b6cd-a889b2aee3d3 ARID=a57ec272-8846-49e6-b458-460b841ed47d > PO-OWIN-CallContext/a57ec272-8846-49e6-b458-460b841ed47d)\"\n"
+
" },\n" +
" \"@permanent\": true\n" +
" }}";

Просмотреть файл

@ -51,8 +51,7 @@ public class AadAuthenticationHelperTest {
@Test
@DisplayName("validate auth with certificate throws exception when missing or invalid parameters")
void acquireWithClientCertificateNullKey() throws CertificateException, OperatorCreationException,
PKCSException, IOException, URISyntaxException, DataServiceException, DataClientException {
void acquireWithClientCertificateNullKey() throws CertificateException, OperatorCreationException, PKCSException, IOException, URISyntaxException, DataServiceException, DataClientException {
String certFilePath = Paths.get("src", "test", "resources", "cert.cer").toString();
String privateKeyPath = Paths.get("src", "test", "resources", "key.pem").toString();
@ -67,12 +66,12 @@ public class AadAuthenticationHelperTest {
aadAuthenticationHelper.initialize();
assertEquals("https://login.microsoftonline.com/organizations/", aadAuthenticationHelper.aadAuthorityUrl);
assertEquals(new HashSet<>(Collections.singletonList("https://kusto.kusto.windows.net/.default")), aadAuthenticationHelper.scopes);
Assertions.assertThrows(DataServiceException.class,
Assertions.assertThrows(
DataServiceException.class,
aadAuthenticationHelper::acquireNewAccessToken);
}
public static KeyCert readPem(String path, String password)
throws IOException, CertificateException, OperatorCreationException, PKCSException {
public static KeyCert readPem(String path, String password) throws IOException, CertificateException, OperatorCreationException, PKCSException {
Security.addProvider(new BouncyCastleProvider());
PEMParser pemParser = new PEMParser(new FileReader(path));
@ -118,18 +117,38 @@ public class AadAuthenticationHelperTest {
MsalTokenProviderBase aadAuthenticationHelperSpy = (MsalTokenProviderBase) spy(TokenProviderFactory.createTokenProvider(csb));
IAuthenticationResult authenticationResult = new MockAuthenticationResult("firstToken", "firstToken", new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()), "environment", "environment", new Date(), Mockito.mock(ITenantProfile.class));
IAuthenticationResult authenticationResultFromRefresh = new MockAuthenticationResult("fromRefresh", "fromRefresh", new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()), "environment", "environment", new Date(), Mockito.mock(ITenantProfile.class));
IAuthenticationResult authenticationResultNullRefreshTokenResult = new MockAuthenticationResult("nullRefreshResult", "nullRefreshResult", new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()), "environment", "environment", new Date(), Mockito.mock(ITenantProfile.class));
IAuthenticationResult authenticationResult = new MockAuthenticationResult(
"firstToken",
"firstToken",
new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()),
"environment",
"environment",
new Date(),
Mockito.mock(ITenantProfile.class));
IAuthenticationResult authenticationResultFromRefresh = new MockAuthenticationResult(
"fromRefresh",
"fromRefresh",
new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()),
"environment",
"environment",
new Date(),
Mockito.mock(ITenantProfile.class));
IAuthenticationResult authenticationResultNullRefreshTokenResult = new MockAuthenticationResult(
"nullRefreshResult",
"nullRefreshResult",
new MockAccount("homeAccountId", "environment", "username", Collections.emptyMap()),
"environment",
"environment",
new Date(),
Mockito.mock(ITenantProfile.class));
//doThrow(DataServiceException.class).when(aadAuthenticationHelperSpy).acquireAccessTokenSilently();
// doThrow(DataServiceException.class).when(aadAuthenticationHelperSpy).acquireAccessTokenSilently();
doReturn(null).when(aadAuthenticationHelperSpy).acquireAccessTokenSilently();
doReturn(authenticationResult).when(aadAuthenticationHelperSpy).acquireNewAccessToken();
assertEquals("firstToken", aadAuthenticationHelperSpy.acquireAccessToken());
assertEquals("https://login.microsoftonline.com/organizations/", aadAuthenticationHelperSpy.aadAuthorityUrl);
assertEquals(new HashSet<>(Collections.singletonList("https://kusto.kusto.windows.net/.default")), aadAuthenticationHelperSpy.scopes);
doReturn(authenticationResultFromRefresh).when(aadAuthenticationHelperSpy).acquireAccessTokenSilently();
// Token was passed as expired - expected to be refreshed
assertEquals("fromRefresh", aadAuthenticationHelperSpy.acquireAccessToken());
@ -148,15 +167,17 @@ public class AadAuthenticationHelperTest {
ConnectionStringBuilder csb = ConnectionStringBuilder.createWithUserPrompt("https://weird.resource.uri", "weird_auth_id", "");
PublicAppTokenProviderBase aadAuthenticationHelper = (PublicAppTokenProviderBase) TokenProviderFactory.createTokenProvider(csb);
CloudInfo.manuallyAddToCache("https://weird.resource.uri", new CloudInfo(
true,
"https://nostandard-login-input",
"non_standard_client_id",
"",
"https://aaaa.kusto.bbbb.com",
"first_party_url"
CloudInfo.manuallyAddToCache(
"https://weird.resource.uri",
new CloudInfo(
true,
"https://nostandard-login-input",
"non_standard_client_id",
"",
"https://aaaa.kusto.bbbb.com",
"first_party_url"
));
));
aadAuthenticationHelper.initialize();
assertEquals("non_standard_client_id", aadAuthenticationHelper.clientApplication.clientId());
@ -167,12 +188,14 @@ public class AadAuthenticationHelperTest {
assertEquals(scopes, aadAuthenticationHelper.scopes);
SilentParameters silentParametersNormalUser = aadAuthenticationHelper.getSilentParameters(
new HashSet<>(Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.115d58c9-f699-44e0-8a53-e1861542e510", "", "", null))));
new HashSet<>(
Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.115d58c9-f699-44e0-8a53-e1861542e510", "", "", null))));
assertEquals(scopes, silentParametersNormalUser.scopes());
assertEquals("https://nostandard-login-input/weird_auth_id/", silentParametersNormalUser.authorityUrl());
SilentParameters silentParametersMsaUser = aadAuthenticationHelper.getSilentParameters(
new HashSet<>(Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.9188040d-6c67-4c5b-b112-36a304b66dad", "", "", null))));
new HashSet<>(
Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.9188040d-6c67-4c5b-b112-36a304b66dad", "", "", null))));
assertEquals(scopes, silentParametersMsaUser.scopes());
assertEquals("first_party_url", silentParametersMsaUser.authorityUrl());
}
@ -196,12 +219,14 @@ public class AadAuthenticationHelperTest {
assertEquals(scopes, aadAuthenticationHelper.scopes);
SilentParameters silentParametersNormalUser = aadAuthenticationHelper.getSilentParameters(
new HashSet<>(Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.115d58c9-f699-44e0-8a53-e1861542e510", "", "", null))));
new HashSet<>(
Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.115d58c9-f699-44e0-8a53-e1861542e510", "", "", null))));
assertEquals(scopes, silentParametersNormalUser.scopes());
assertEquals(authorityUrl, silentParametersNormalUser.authorityUrl());
SilentParameters silentParametersMsaUser = aadAuthenticationHelper.getSilentParameters(
new HashSet<>(Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.9188040d-6c67-4c5b-b112-36a304b66dad", "", "", null))));
new HashSet<>(
Collections.singletonList(new MockAccount("c0327b6e-814d-4194-8e7f-9fc7a1e5dea9.9188040d-6c67-4c5b-b112-36a304b66dad", "", "", null))));
assertEquals(scopes, silentParametersMsaUser.scopes());
assertEquals(CloudInfo.DEFAULT_FIRST_PARTY_AUTHORITY_URL, silentParametersMsaUser.authorityUrl());
}
@ -249,7 +274,14 @@ public class AadAuthenticationHelperTest {
private final Date expiresOnDate;
private final ITenantProfile tenantProfile;
public MockAuthenticationResult(String accessToken, String idToken, MockAccount account, String environment, String scopes, Date expiresOnDate, ITenantProfile tenantProfile) {
public MockAuthenticationResult(
String accessToken,
String idToken,
MockAccount account,
String environment,
String scopes,
Date expiresOnDate,
ITenantProfile tenantProfile) {
this.accessToken = accessToken;
this.idToken = idToken;
this.account = account;

Просмотреть файл

@ -30,4 +30,4 @@ public class KeyCert {
void setKey(PrivateKey key) {
this.key = key;
}
}
}

Просмотреть файл

@ -257,4 +257,4 @@
<version>${httpcore.version}</version>
</dependency>
</dependencies>
</project>
</project>

Просмотреть файл

@ -44,8 +44,7 @@ class AzureStorageClient {
queue.addMessage(queueMessage);
}
void azureTableInsertEntity(String tableUri, TableServiceEntity entity) throws StorageException,
URISyntaxException {
void azureTableInsertEntity(String tableUri, TableServiceEntity entity) throws StorageException, URISyntaxException {
// Ensure
Ensure.stringIsNotBlank(tableUri, "tableUri");
Ensure.argIsNotNull(entity, "entity");
@ -57,16 +56,22 @@ class AzureStorageClient {
table.execute(insert);
}
CloudBlockBlob uploadLocalFileToBlob(String filePath, String blobName, String storageUri, IngestionProperties.DataFormat dataFormat)
throws URISyntaxException, StorageException, IOException {
CloudBlockBlob uploadLocalFileToBlob(
String filePath,
String blobName,
String storageUri,
IngestionProperties.DataFormat dataFormat) throws URISyntaxException, StorageException, IOException {
Ensure.fileExists(filePath);
CompressionType sourceCompressionType = getCompression(filePath);
return uploadLocalFileToBlob(filePath, blobName, storageUri, IngestClientBase.shouldCompress(sourceCompressionType, dataFormat));
}
CloudBlockBlob uploadLocalFileToBlob(String filePath, String blobName, String storageUri, boolean shouldCompress)
throws URISyntaxException, StorageException, IOException {
CloudBlockBlob uploadLocalFileToBlob(
String filePath,
String blobName,
String storageUri,
boolean shouldCompress) throws URISyntaxException, StorageException, IOException {
log.debug("uploadLocalFileToBlob: filePath: {}, blobName: {}, storageUri: {}", filePath, blobName, storageUri);
// Ensure
@ -93,7 +98,7 @@ class AzureStorageClient {
Ensure.argIsNotNull(blob, "blob");
try (InputStream fin = Files.newInputStream(Paths.get(filePath));
GZIPOutputStream gzout = new GZIPOutputStream(blob.openOutputStream())) {
GZIPOutputStream gzout = new GZIPOutputStream(blob.openOutputStream())) {
copyStream(fin, gzout, GZIP_BUFFER_SIZE);
}
}
@ -106,8 +111,11 @@ class AzureStorageClient {
blob.uploadFromFile(sourceFile.getAbsolutePath());
}
CloudBlockBlob uploadStreamToBlob(InputStream inputStream, String blobName, String storageUri, boolean shouldCompress)
throws IOException, URISyntaxException, StorageException {
CloudBlockBlob uploadStreamToBlob(
InputStream inputStream,
String blobName,
String storageUri,
boolean shouldCompress) throws IOException, URISyntaxException, StorageException {
log.debug("uploadStreamToBlob: blobName: {}, storageUri: {}", blobName, storageUri);
// Ensure
@ -157,8 +165,7 @@ class AzureStorageClient {
String getBlobPathWithSas(CloudBlockBlob blob) {
Ensure.argIsNotNull(blob, "blob");
StorageCredentialsSharedAccessSignature signature =
(StorageCredentialsSharedAccessSignature) blob.getServiceClient().getCredentials();
StorageCredentialsSharedAccessSignature signature = (StorageCredentialsSharedAccessSignature) blob.getServiceClient().getCredentials();
return blob.getStorageUri().getPrimaryUri().toString() + "?" + signature.getToken();
}
@ -193,4 +200,4 @@ class AzureStorageClient {
return filename.substring(0, extensionPos);
}
}
}
}

Просмотреть файл

@ -124,4 +124,4 @@ public class ColumnMapping implements Serializable {
return false;
}
}
}
}

Просмотреть файл

@ -36,8 +36,7 @@ public class ExponentialRetry {
if (result != null) {
return result;
}
}
catch (Exception e) {
} catch (Exception e) {
log.error("execute: Error is permanent, stopping", e);
throw e;
}
@ -59,5 +58,4 @@ public class ExponentialRetry {
return null;
}
}

Просмотреть файл

@ -28,8 +28,9 @@ public interface IngestClient extends Closeable {
* @see FileSourceInfo
* @see IngestionProperties
*/
IngestionResult ingestFromFile(FileSourceInfo fileSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException;
IngestionResult ingestFromFile(
FileSourceInfo fileSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException;
/**
* <p>Ingest data from a blob storage into Kusto database.</p>
@ -44,8 +45,9 @@ public interface IngestClient extends Closeable {
* @see BlobSourceInfo
* @see IngestionProperties
*/
IngestionResult ingestFromBlob(BlobSourceInfo blobSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException;
IngestionResult ingestFromBlob(
BlobSourceInfo blobSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException;
/**
* <p>Ingest data from a Result Set into Kusto database.</p>
@ -63,8 +65,9 @@ public interface IngestClient extends Closeable {
* @see ResultSetSourceInfo
* @see IngestionProperties
*/
IngestionResult ingestFromResultSet(ResultSetSourceInfo resultSetSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException;
IngestionResult ingestFromResultSet(
ResultSetSourceInfo resultSetSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException;
/**
* <p>Ingest data from an input stream, into Kusto database.</p>
@ -79,7 +82,8 @@ public interface IngestClient extends Closeable {
* @see StreamSourceInfo
* @see IngestionProperties
*/
IngestionResult ingestFromStream(StreamSourceInfo streamSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException;
IngestionResult ingestFromStream(
StreamSourceInfo streamSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException;
}

Просмотреть файл

@ -17,10 +17,11 @@ public abstract class IngestClientBase {
private String endpointServiceType;
private String suggestedEndpointUri;
public static final String INGEST_PREFIX = "ingest-";
protected static final String WRONG_ENDPOINT_MESSAGE =
"You are using '%s' client type, but the provided endpoint is of ServiceType '%s'. Initialize the client with the appropriate endpoint URI";
protected static final String WRONG_ENDPOINT_MESSAGE = "You are using '%s' client type, but the provided endpoint is of ServiceType '%s'. Initialize the client with the appropriate endpoint URI";
protected void validateEndpointServiceType(String connectionDataSource, String expectedServiceType) throws IngestionServiceException, IngestionClientException {
protected void validateEndpointServiceType(
String connectionDataSource,
String expectedServiceType) throws IngestionServiceException, IngestionClientException {
if (StringUtils.isBlank(endpointServiceType)) {
endpointServiceType = retrieveServiceType();
}
@ -64,4 +65,4 @@ public abstract class IngestClientBase {
static boolean shouldCompress(CompressionType sourceCompressionType, IngestionProperties.DataFormat dataFormat) {
return (sourceCompressionType == null) && (dataFormat == null || dataFormat.isCompressible());
}
}
}

Просмотреть файл

@ -20,8 +20,9 @@ public class IngestClientFactory {
return new StreamingIngestClient(csb);
}
public static ManagedStreamingIngestClient createManagedStreamingIngestClient(ConnectionStringBuilder dmConnectionStringBuilder,
ConnectionStringBuilder engineConnectionStringBuilder) throws URISyntaxException {
public static ManagedStreamingIngestClient createManagedStreamingIngestClient(
ConnectionStringBuilder dmConnectionStringBuilder,
ConnectionStringBuilder engineConnectionStringBuilder) throws URISyntaxException {
return new ManagedStreamingIngestClient(dmConnectionStringBuilder, engineConnectionStringBuilder);
}
}
}

Просмотреть файл

@ -19,8 +19,7 @@ public final class IngestionBlobInfo {
private String reportLevel;
private String reportMethod;
@JsonInclude(JsonInclude.Include.NON_NULL)
private ValidationPolicy validationPolicy;
@JsonInclude(JsonInclude.Include.NON_NULL) private ValidationPolicy validationPolicy;
private Boolean flushImmediately;
private IngestionStatusInTableDescription ingestionStatusInTable;
@ -116,4 +115,4 @@ public final class IngestionBlobInfo {
public void setValidationPolicy(ValidationPolicy validationPolicy) {
this.validationPolicy = validationPolicy;
}
}
}

Просмотреть файл

@ -91,8 +91,8 @@ public class IngestionMapping {
}
/*
Represents an ingestion mapping kind - the format of the source data to map from.
*/
* Represents an ingestion mapping kind - the format of the source data to map from.
*/
public enum IngestionMappingKind {
CSV("Csv"),
JSON("Json"),
@ -113,4 +113,4 @@ public class IngestionMapping {
return kustoValue;
}
}
}
}

Просмотреть файл

@ -69,6 +69,7 @@ public class IngestionProperties {
this.ingestionMapping = new IngestionMapping();
this.dataFormat = DataFormat.CSV;
}
/**
* Copy constructor for {@code IngestionProperties}.
*
@ -275,7 +276,9 @@ public class IngestionProperties {
try {
this.dataFormat = DataFormat.valueOf(dataFormatName.toUpperCase());
} catch (IllegalArgumentException ex) {
log.warn("IngestionProperties.setDataFormat(): Invalid dataFormatName of {}. Per the API's specification, DataFormat property value wasn't set.", dataFormatName);
log.warn(
"IngestionProperties.setDataFormat(): Invalid dataFormatName of {}. Per the API's specification, DataFormat property value wasn't set.",
dataFormatName);
}
}
@ -341,8 +344,11 @@ public class IngestionProperties {
}
} else { // a mapping was provided
if (dataFormat.getIngestionMappingKind() != null && !dataFormat.getIngestionMappingKind().equals(ingestionMappingKind)) {
message.appendln("Wrong ingestion mapping for format '%s'; mapping kind should be '%s', but was '%s'.",
dataFormat.getKustoValue(), dataFormat.getIngestionMappingKind().getKustoValue(), ingestionMappingKind != null ? ingestionMappingKind.getKustoValue() : "null");
message.appendln(
"Wrong ingestion mapping for format '%s'; mapping kind should be '%s', but was '%s'.",
dataFormat.getKustoValue(),
dataFormat.getIngestionMappingKind().getKustoValue(),
ingestionMappingKind != null ? ingestionMappingKind.getKustoValue() : "null");
}
if (ingestionMapping.getColumnMappings() != null) {
@ -368,7 +374,8 @@ public class IngestionProperties {
}
public void validateResultSetProperties() throws IngestionClientException {
Ensure.isTrue(IngestionProperties.DataFormat.CSV.equals(dataFormat),
Ensure.isTrue(
IngestionProperties.DataFormat.CSV.equals(dataFormat),
String.format("ResultSet translates into csv format but '%s' was given", dataFormat));
validate();
@ -447,4 +454,4 @@ public class IngestionProperties {
return kustoValue;
}
}
}
}

Просмотреть файл

@ -70,4 +70,4 @@ public class IngestionUtils {
return buffer.toByteArray();
}
}
}

Просмотреть файл

@ -75,27 +75,30 @@ public class ManagedStreamingIngestClient implements IngestClient {
return new ManagedStreamingIngestClient(dmConnectionString, engineConnectionString);
}
public ManagedStreamingIngestClient(ConnectionStringBuilder dmConnectionStringBuilder,
ConnectionStringBuilder engineConnectionStringBuilder) throws URISyntaxException {
public ManagedStreamingIngestClient(
ConnectionStringBuilder dmConnectionStringBuilder,
ConnectionStringBuilder engineConnectionStringBuilder) throws URISyntaxException {
log.info("Creating a new ManagedStreamingIngestClient from connection strings");
queuedIngestClient = new QueuedIngestClient(dmConnectionStringBuilder);
streamingIngestClient = new StreamingIngestClient(engineConnectionStringBuilder);
exponentialRetryTemplate = new ExponentialRetry(ATTEMPT_COUNT);
}
public ManagedStreamingIngestClient(ResourceManager resourceManager,
AzureStorageClient storageClient,
StreamingClient streamingClient) {
public ManagedStreamingIngestClient(
ResourceManager resourceManager,
AzureStorageClient storageClient,
StreamingClient streamingClient) {
log.info("Creating a new ManagedStreamingIngestClient from raw parts");
queuedIngestClient = new QueuedIngestClient(resourceManager, storageClient);
streamingIngestClient = new StreamingIngestClient(streamingClient);
exponentialRetryTemplate = new ExponentialRetry(ATTEMPT_COUNT);
}
ManagedStreamingIngestClient(ResourceManager resourceManager,
AzureStorageClient storageClient,
StreamingClient streamingClient,
ExponentialRetry retryTemplate) {
ManagedStreamingIngestClient(
ResourceManager resourceManager,
AzureStorageClient storageClient,
StreamingClient streamingClient,
ExponentialRetry retryTemplate) {
log.info("Creating a new ManagedStreamingIngestClient from raw parts");
queuedIngestClient = new QueuedIngestClient(resourceManager, storageClient);
streamingIngestClient = new StreamingIngestClient(streamingClient);
@ -103,7 +106,9 @@ public class ManagedStreamingIngestClient implements IngestClient {
}
@Override
public IngestionResult ingestFromFile(FileSourceInfo fileSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromFile(
FileSourceInfo fileSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(fileSourceInfo, "fileSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -124,7 +129,9 @@ public class ManagedStreamingIngestClient implements IngestClient {
* This method behaves differently from the rest for {@link ManagedStreamingIngestClient} - since a blob already exists it makes more sense to enqueue it rather than downloading and streaming it, thus ManagedStreamingIngestClient skips the streaming retries and sends it directly to the queued client.</p>
*/
@Override
public IngestionResult ingestFromBlob(BlobSourceInfo blobSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromBlob(
BlobSourceInfo blobSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(blobSourceInfo, "blobSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -136,7 +143,9 @@ public class ManagedStreamingIngestClient implements IngestClient {
}
@Override
public IngestionResult ingestFromResultSet(ResultSetSourceInfo resultSetSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromResultSet(
ResultSetSourceInfo resultSetSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(resultSetSourceInfo, "resultSetSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -153,7 +162,9 @@ public class ManagedStreamingIngestClient implements IngestClient {
}
@Override
public IngestionResult ingestFromStream(StreamSourceInfo streamSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromStream(
StreamSourceInfo streamSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(streamSourceInfo, "streamSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -177,8 +188,11 @@ public class ManagedStreamingIngestClient implements IngestClient {
if (streamingBytes.length > MAX_STREAMING_SIZE_BYTES) {
log.info("Stream size is greater than max streaming size ({} bytes). Falling back to queued.", streamingBytes.length);
StreamSourceInfo managedSourceInfo = new StreamSourceInfo(new SequenceInputStream(byteArrayStream, streamSourceInfo.getStream()),
streamSourceInfo.isLeaveOpen(), sourceId, streamSourceInfo.getCompressionType());
StreamSourceInfo managedSourceInfo = new StreamSourceInfo(
new SequenceInputStream(byteArrayStream, streamSourceInfo.getStream()),
streamSourceInfo.isLeaveOpen(),
sourceId,
streamSourceInfo.getCompressionType());
return queuedIngestClient.ingestFromStream(managedSourceInfo, ingestionProperties);
}
@ -248,4 +262,4 @@ public class ManagedStreamingIngestClient implements IngestClient {
queuedIngestClient.close();
streamingIngestClient.close();
}
}
}

Просмотреть файл

@ -26,4 +26,3 @@ public enum MappingConsts {
return name;
}
}

Просмотреть файл

@ -77,8 +77,9 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
}
@Override
public IngestionResult ingestFromBlob(BlobSourceInfo blobSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromBlob(
BlobSourceInfo blobSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
// Argument validation:
Ensure.argIsNotNull(blobSourceInfo, "blobSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -91,8 +92,10 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
List<IngestionStatusInTableDescription> tableStatuses = new LinkedList<>();
// Create the ingestion message
IngestionBlobInfo ingestionBlobInfo = new IngestionBlobInfo(blobSourceInfo.getBlobPath(),
ingestionProperties.getDatabaseName(), ingestionProperties.getTableName());
IngestionBlobInfo ingestionBlobInfo = new IngestionBlobInfo(
blobSourceInfo.getBlobPath(),
ingestionProperties.getDatabaseName(),
ingestionProperties.getTableName());
String urlWithoutSecrets = SecurityUtils.removeSecretsFromUrl(blobSourceInfo.getBlobPath());
if (blobSourceInfo.getRawSizeInBytes() > 0L) {
ingestionBlobInfo.setRawDataSize(blobSourceInfo.getRawSizeInBytes());
@ -116,8 +119,8 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
status.updatedOn = Date.from(Instant.now());
status.ingestionSourceId = ingestionBlobInfo.getId();
status.setIngestionSourcePath(urlWithoutSecrets);
boolean reportToTable = ingestionProperties.getReportLevel() != IngestionProperties.IngestionReportLevel.NONE &&
ingestionProperties.getReportMethod() != IngestionProperties.IngestionReportMethod.QUEUE;
boolean reportToTable = ingestionProperties.getReportLevel() != IngestionProperties.IngestionReportLevel.NONE &&
ingestionProperties.getReportMethod() != IngestionProperties.IngestionReportMethod.QUEUE;
if (reportToTable) {
status.status = OperationStatus.Pending;
String tableStatusUri = resourceManager
@ -136,8 +139,8 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
azureStorageClient.postMessageToQueue(
resourceManager
.getIngestionResource(ResourceManager.ResourceType.SECURED_READY_FOR_AGGREGATION_QUEUE)
, serializedIngestionBlobInfo);
.getIngestionResource(ResourceManager.ResourceType.SECURED_READY_FOR_AGGREGATION_QUEUE),
serializedIngestionBlobInfo);
return reportToTable
? new TableReportIngestionResult(tableStatuses)
: new IngestionStatusResult(status);
@ -152,8 +155,9 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
}
@Override
public IngestionResult ingestFromFile(FileSourceInfo fileSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromFile(
FileSourceInfo fileSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
// Argument validation:
Ensure.argIsNotNull(fileSourceInfo, "fileSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -176,11 +180,14 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
dataFormat.getKustoValue(), // Used to use an empty string if the DataFormat was empty. Now it can't be empty, with a default of CSV.
shouldCompress ? CompressionType.gz : sourceCompressionType);
CloudBlockBlob blob = azureStorageClient.uploadLocalFileToBlob(fileSourceInfo.getFilePath(), blobName,
resourceManager.getIngestionResource(ResourceManager.ResourceType.TEMP_STORAGE), shouldCompress);
CloudBlockBlob blob = azureStorageClient.uploadLocalFileToBlob(
fileSourceInfo.getFilePath(),
blobName,
resourceManager.getIngestionResource(ResourceManager.ResourceType.TEMP_STORAGE),
shouldCompress);
String blobPath = azureStorageClient.getBlobPathWithSas(blob);
long rawDataSize = fileSourceInfo.getRawSizeInBytes() > 0L ? fileSourceInfo.getRawSizeInBytes() :
estimateFileRawSize(filePath, dataFormat.isCompressible());
long rawDataSize = fileSourceInfo.getRawSizeInBytes() > 0L ? fileSourceInfo.getRawSizeInBytes()
: estimateFileRawSize(filePath, dataFormat.isCompressible());
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(blobPath, rawDataSize, fileSourceInfo.getSourceId());
@ -196,8 +203,9 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
}
@Override
public IngestionResult ingestFromStream(StreamSourceInfo streamSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromStream(
StreamSourceInfo streamSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
// Argument validation:
Ensure.argIsNotNull(streamSourceInfo, "streamSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -226,11 +234,11 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
streamSourceInfo.getStream(),
blobName,
resourceManager.getIngestionResource(ResourceManager.ResourceType.TEMP_STORAGE),
shouldCompress
);
shouldCompress);
String blobPath = azureStorageClient.getBlobPathWithSas(blob);
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(
blobPath, 0); // TODO: check if we can get the rawDataSize locally - maybe add a countingStream
blobPath,
0); // TODO: check if we can get the rawDataSize locally - maybe add a countingStream
ingestionResult = ingestFromBlob(blobSourceInfo, ingestionProperties);
if (!streamSourceInfo.isLeaveOpen()) {
@ -249,12 +257,12 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
private long estimateFileRawSize(String filePath, boolean isCompressible) {
long fileSize = new File(filePath).length();
return (AzureStorageClient.getCompression(filePath) != null || !isCompressible) ?
fileSize * COMPRESSED_FILE_MULTIPLIER : fileSize;
return (AzureStorageClient.getCompression(filePath) != null || !isCompressible) ? fileSize * COMPRESSED_FILE_MULTIPLIER : fileSize;
}
String genBlobName(String fileName, String databaseName, String tableName, String dataFormat, CompressionType compressionType) {
return String.format("%s__%s__%s__%s%s%s",
return String.format(
"%s__%s__%s__%s%s%s",
databaseName,
tableName,
AzureStorageClient.removeExtension(fileName),
@ -264,8 +272,9 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
}
@Override
public IngestionResult ingestFromResultSet(ResultSetSourceInfo resultSetSourceInfo, IngestionProperties ingestionProperties)
throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromResultSet(
ResultSetSourceInfo resultSetSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
// Argument validation:
Ensure.argIsNotNull(resultSetSourceInfo, "resultSetSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -308,4 +317,4 @@ public class QueuedIngestClient extends IngestClientBase implements IngestClient
public void close() {
this.resourceManager.close();
}
}
}

Просмотреть файл

@ -215,9 +215,15 @@ class ResourceManager implements Closeable {
return resultTable.getString(SERVICE_TYPE_COLUMN_NAME);
}
} catch (DataServiceException e) {
throw new IngestionServiceException(e.getIngestionSource(), "Couldn't retrieve ServiceType because of a service exception executing '.show version'", e);
throw new IngestionServiceException(
e.getIngestionSource(),
"Couldn't retrieve ServiceType because of a service exception executing '.show version'",
e);
} catch (DataClientException e) {
throw new IngestionClientException(e.getIngestionSource(), "Couldn't retrieve ServiceType because of a client exception executing '.show version'", e);
throw new IngestionClientException(
e.getIngestionSource(),
"Couldn't retrieve ServiceType because of a client exception executing '.show version'",
e);
}
throw new IngestionServiceException("Couldn't retrieve ServiceType because '.show version' didn't return any records");
}
@ -241,4 +247,4 @@ class ResourceManager implements Closeable {
return storageUrls.get(roundRobinIdx);
}
}
}
}

Просмотреть файл

@ -73,4 +73,4 @@ public class SecurityUtils {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
return (RSAPublicKey) kf.generatePublic(keySpec);
}
}
}

Просмотреть файл

@ -68,7 +68,9 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
}
@Override
public IngestionResult ingestFromFile(FileSourceInfo fileSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromFile(
FileSourceInfo fileSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(fileSourceInfo, "fileSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -85,7 +87,9 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
}
@Override
public IngestionResult ingestFromBlob(BlobSourceInfo blobSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromBlob(
BlobSourceInfo blobSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
log.warn("Ingesting from blob using the StreamingIngestClient is not recommended, consider using the IngestClient instead.");
Ensure.argIsNotNull(blobSourceInfo, "blobSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -108,7 +112,9 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
}
@Override
public IngestionResult ingestFromResultSet(ResultSetSourceInfo resultSetSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromResultSet(
ResultSetSourceInfo resultSetSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
// Argument validation:
Ensure.argIsNotNull(resultSetSourceInfo, "resultSetSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -127,11 +133,16 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
}
@Override
public IngestionResult ingestFromStream(StreamSourceInfo streamSourceInfo, IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
public IngestionResult ingestFromStream(
StreamSourceInfo streamSourceInfo,
IngestionProperties ingestionProperties) throws IngestionClientException, IngestionServiceException {
return ingestFromStream(streamSourceInfo, ingestionProperties, null);
}
IngestionResult ingestFromStream(StreamSourceInfo streamSourceInfo, IngestionProperties ingestionProperties, @Nullable String clientRequestId) throws IngestionClientException, IngestionServiceException {
IngestionResult ingestFromStream(
StreamSourceInfo streamSourceInfo,
IngestionProperties ingestionProperties,
@Nullable String clientRequestId) throws IngestionClientException, IngestionServiceException {
Ensure.argIsNotNull(streamSourceInfo, "streamSourceInfo");
Ensure.argIsNotNull(ingestionProperties, "ingestionProperties");
@ -147,9 +158,12 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
}
try {
InputStream stream = IngestClientBase.shouldCompress(streamSourceInfo.getCompressionType(), dataFormat) ? compressStream(streamSourceInfo.getStream(), streamSourceInfo.isLeaveOpen()) : streamSourceInfo.getStream();
InputStream stream = IngestClientBase.shouldCompress(streamSourceInfo.getCompressionType(), dataFormat)
? compressStream(streamSourceInfo.getStream(), streamSourceInfo.isLeaveOpen())
: streamSourceInfo.getStream();
log.debug("Executing streaming ingest");
this.streamingClient.executeStreamingIngest(ingestionProperties.getDatabaseName(),
this.streamingClient.executeStreamingIngest(
ingestionProperties.getDatabaseName(),
ingestionProperties.getTableName(),
stream,
clientRequestProperties,
@ -199,7 +213,10 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
return inputStream;
}
IngestionResult ingestFromBlob(BlobSourceInfo blobSourceInfo, IngestionProperties ingestionProperties, CloudBlockBlob cloudBlockBlob) throws IngestionClientException, IngestionServiceException, StorageException {
IngestionResult ingestFromBlob(
BlobSourceInfo blobSourceInfo,
IngestionProperties ingestionProperties,
CloudBlockBlob cloudBlockBlob) throws IngestionClientException, IngestionServiceException, StorageException {
String blobPath = blobSourceInfo.getBlobPath();
cloudBlockBlob.downloadAttributes();
if (cloudBlockBlob.getProperties().getLength() == 0) {
@ -229,9 +246,15 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
return resultTable.getString(ResourceManager.SERVICE_TYPE_COLUMN_NAME);
}
} catch (DataServiceException e) {
throw new IngestionServiceException(e.getIngestionSource(), "Couldn't retrieve ServiceType because of a service exception executing '.show version'", e);
throw new IngestionServiceException(
e.getIngestionSource(),
"Couldn't retrieve ServiceType because of a service exception executing '.show version'",
e);
} catch (DataClientException e) {
throw new IngestionClientException(e.getIngestionSource(), "Couldn't retrieve ServiceType because of a client exception executing '.show version'", e);
throw new IngestionClientException(
e.getIngestionSource(),
"Couldn't retrieve ServiceType because of a client exception executing '.show version'",
e);
}
throw new IngestionServiceException("Couldn't retrieve ServiceType because '.show version' didn't return any records");
}
@ -245,4 +268,4 @@ public class StreamingIngestClient extends IngestClientBase implements IngestCli
@Override
public void close() {
}
}
}

Просмотреть файл

@ -7,8 +7,7 @@ package com.microsoft.azure.kusto.ingest;
* Transformation method can be used over all formats configured with Json mapping type (Json, Orc and Parquet)
* See <a href="https://docs.microsoft.com/en-us/azure/kusto/management/mappings#json-mapping">kusto docs</a>
*/
public enum TransformationMethod
{
public enum TransformationMethod {
/**
* Comma-separated value.
*/
@ -59,4 +58,4 @@ public enum TransformationMethod
*/
DateTimeFromUnixNanoseconds,
}
}

Просмотреть файл

@ -6,7 +6,9 @@ package com.microsoft.azure.kusto.ingest.exceptions;
public class IngestionClientException extends Exception {
private String ingestionSource;
public String getIngestionSource() { return ingestionSource; }
public String getIngestionSource() {
return ingestionSource;
}
public IngestionClientException(String message) {
super(message);

Просмотреть файл

@ -6,7 +6,9 @@ package com.microsoft.azure.kusto.ingest.exceptions;
public class IngestionServiceException extends Exception {
private String ingestionSource;
public String getIngestionSource() { return ingestionSource; }
public String getIngestionSource() {
return ingestionSource;
}
public IngestionServiceException(String message) {
super(message);

Просмотреть файл

@ -8,62 +8,62 @@ public enum IngestionErrorCode {
/// Unknown error occurred
/// </summary>
Unknown,
/// <summary>
/// Low memory condition.
/// </summary>
Stream_LowMemoryCondition,
/// <summary>
/// Wrong number of fields.
/// </summary>
Stream_WrongNumberOfFields,
/// <summary>
/// Input stream/record/field too large.
/// </summary>
Stream_InputStreamTooLarge,
/// <summary>
/// No data streams to ingest
/// </summary>
Stream_NoDataToIngest,
/// <summary>
/// Invalid csv format - closing quote missing.
/// </summary>
Stream_ClosingQuoteMissing,
/// <summary>
/// Failed to download source from Azure storage - source not found
/// </summary>
Download_SourceNotFound,
/// <summary>
/// Failed to download source from Azure storage - access condition not satisfied
/// </summary>
Download_AccessConditionNotSatisfied,
/// <summary>
/// Failed to download source from Azure storage - access forbidden
/// </summary>
Download_Forbidden,
/// <summary>
/// Failed to download source from Azure storage - account not found
/// </summary>
Download_AccountNotFound,
/// <summary>
/// Failed to download source from Azure storage - bad request
/// </summary>
Download_BadRequest,
/// <summary>
/// Failed to download source from Azure storage - not transient error
/// </summary>
Download_NotTransient,
/// <summary>
/// Failed to download source from Azure storage - Unknown error
/// </summary>
@ -83,42 +83,42 @@ public enum IngestionErrorCode {
/// Failed to invoke update policy. Query schema does not match table schema
/// </summary>
UpdatePolicy_QuerySchemaDoesNotMatchTableSchema,
/// <summary>
/// Failed to invoke update policy. Failed descendant transactional update policy
/// </summary>
UpdatePolicy_FailedDescendantTransaction,
/// <summary>
/// Failed to invoke update policy. Ingestion Error occurred
/// </summary>
UpdatePolicy_IngestionError,
/// <summary>
/// Failed to invoke update policy. Unknown error occurred
/// </summary>
UpdatePolicy_UnknownError,
/// <summary>
/// Json pattern was not ingested with jsonMapping parameter
/// </summary>
BadRequest_MissingJsonMappingtFailure,
/// <summary>
/// Blob is invalid or empty zip archive
/// </summary>
BadRequest_InvalidOrEmptyBlob,
/// <summary>
/// Database does not exist
/// </summary>
BadRequest_DatabaseNotExist,
/// <summary>
/// Table does not exist
/// </summary>
BadRequest_TableNotExist,
/// <summary>
/// Invalid kusto identity token
/// </summary>
@ -133,42 +133,42 @@ public enum IngestionErrorCode {
/// Blob path without SAS from Unknown blob storage
/// </summary>
BadRequest_UriMissingSas,
/// <summary>
/// File too large
/// </summary>
BadRequest_FileTooLarge,
/// <summary>
/// No valid reply from ingest command
/// </summary>
BadRequest_NoValidResponseFromEngine,
/// <summary>
/// Access to table is denied
/// </summary>
BadRequest_TableAccessDenied,
/// <summary>
/// Message is exhausted
/// </summary>
BadRequest_MessageExhausted,
/// <summary>
/// Bad request
/// </summary>
General_BadRequest,
/// <summary>
/// Internal server error occurred
/// </summary>
General_InternalServerError,
/// <summary>
/// Failed to invoke update policy. Cyclic update is not allowed
/// </summary>
UpdatePolicy_Cyclic_Update_Not_Allowed,
/// <summary>
/// Failed to invoke update policy. Transactional update policy is not allowed in streaming ingestion
/// </summary>
@ -218,7 +218,7 @@ public enum IngestionErrorCode {
/// Invalid mapping reference.
/// </summary>
BadRequest_InvalidMappingReference,
/// <summary>
/// Mapping reference wasn't found.
/// </summary>
@ -258,12 +258,12 @@ public enum IngestionErrorCode {
/// Message is corrupted
/// </summary>
BadRequest_CorruptedMessage,
/// <summary>
/// Inconsistent ingestion mapping
/// </summary>
BadRequest_InconsistentMapping,
/// <summary>
/// Syntax error
/// </summary>
@ -313,12 +313,12 @@ public enum IngestionErrorCode {
/// Abandoned ingestion.
/// </summary>
General_AbandonedIngestion,
/// <summary>
/// Throttled ingestion.
/// </summary>
General_ThrottledIngestion,
/// <summary>
/// Schema of target table at start time doesn't match the one at commit time.
/// </summary>

Просмотреть файл

@ -35,4 +35,3 @@ public class IngestionFailureInfo {
}
}
}

Просмотреть файл

@ -11,9 +11,10 @@ import java.util.List;
public interface IngestionResult extends Serializable {
/// <summary>
/// Retrieves the detailed ingestion status of
/// Retrieves the detailed ingestion status of
/// all data ingestion operations into Kusto associated with this com.microsoft.azure.kusto.ingest.IKustoIngestionResult instance.
/// </summary>
List<IngestionStatus> getIngestionStatusCollection() throws StorageException, URISyntaxException;
int getIngestionStatusesLength();
}

Просмотреть файл

@ -25,7 +25,7 @@ public class IngestionStatus extends TableServiceEntity {
public String getStatus() {
return status.toString();
}
public void setStatus(String s) {
status = OperationStatus.valueOf(s);
}
@ -138,9 +138,9 @@ public class IngestionStatus extends TableServiceEntity {
public void setErrorCode(String code) {
errorCodeString = code;
try{
try {
errorCode = code == null ? IngestionErrorCode.Unknown : IngestionErrorCode.valueOf(code);
} catch (IllegalArgumentException ex){
} catch (IllegalArgumentException ex) {
errorCode = IngestionErrorCode.Misc;
}
}

Просмотреть файл

@ -33,4 +33,4 @@ public class IngestionStatusInTableDescription implements Serializable {
public void setRowKey(String rowKey) {
this.rowKey = rowKey;
}
}
}

Просмотреть файл

@ -23,4 +23,4 @@ public class IngestionStatusResult implements IngestionResult {
public int getIngestionStatusesLength() {
return 1;
}
}
}

Просмотреть файл

@ -24,7 +24,9 @@ public class TableReportIngestionResult implements IngestionResult {
List<IngestionStatus> results = new LinkedList<>();
for (IngestionStatusInTableDescription descriptor : descriptors) {
CloudTable table = new CloudTable(new URI(descriptor.getTableConnectionString()));
TableOperation operation = TableOperation.retrieve(descriptor.getPartitionKey(), descriptor.getRowKey(),
TableOperation operation = TableOperation.retrieve(
descriptor.getPartitionKey(),
descriptor.getRowKey(),
IngestionStatus.class);
results.add(table.execute(operation).getResultAsType());
}
@ -36,4 +38,4 @@ public class TableReportIngestionResult implements IngestionResult {
public int getIngestionStatusesLength() {
return descriptors.size();
}
}
}

Просмотреть файл

@ -7,7 +7,6 @@ import java.util.UUID;
import static com.microsoft.azure.kusto.data.Ensure.stringIsNotBlank;
public class BlobSourceInfo extends AbstractSourceInfo {
private String blobPath;

Просмотреть файл

@ -7,7 +7,6 @@ import java.util.UUID;
import static com.microsoft.azure.kusto.data.Ensure.stringIsNotBlank;
public class FileSourceInfo extends AbstractSourceInfo {
private String filePath;

Просмотреть файл

@ -59,6 +59,6 @@ public class ResultSetSourceInfo extends AbstractSourceInfo {
}
public void validate() {
//nothing to validate as of now.
// nothing to validate as of now.
}
}

Просмотреть файл

@ -75,4 +75,3 @@ public class StreamSourceInfo extends AbstractSourceInfo {
return String.format("Stream with SourceId: %s", getSourceId());
}
}

Просмотреть файл

@ -78,8 +78,7 @@ class AzureStorageClientTest {
}
@Test
void UploadLocalFileToBlob_UncompressedFile_CompressAndUploadFileToBlobIsCalled()
throws IOException, StorageException, URISyntaxException {
void UploadLocalFileToBlob_UncompressedFile_CompressAndUploadFileToBlobIsCalled() throws IOException, StorageException, URISyntaxException {
doNothing().when(azureStorageClientSpy).compressAndUploadFileToBlob(anyString(), any(CloudBlockBlob.class));
azureStorageClientSpy.uploadLocalFileToBlob(testFilePath, "blobName", "https://testcontosourl.com/blob", IngestionProperties.DataFormat.CSV);
@ -87,8 +86,7 @@ class AzureStorageClientTest {
}
@Test
void UploadLocalFileToBlob_CompressedFile_UploadFileToBlobIsCalled()
throws IOException, StorageException, URISyntaxException {
void UploadLocalFileToBlob_CompressedFile_UploadFileToBlobIsCalled() throws IOException, StorageException, URISyntaxException {
doNothing().when(azureStorageClientSpy).uploadFileToBlob(any(File.class), any(CloudBlockBlob.class));
azureStorageClientSpy.uploadLocalFileToBlob(testFilePathCompressed, "blobName", "https://testcontosourl.com/blob", IngestionProperties.DataFormat.CSV);
@ -125,8 +123,7 @@ class AzureStorageClientTest {
}
@Test
void UploadStreamToBlob_NotCompressMode_UploadStreamIsCalled()
throws IOException, URISyntaxException, StorageException {
void UploadStreamToBlob_NotCompressMode_UploadStreamIsCalled() throws IOException, URISyntaxException, StorageException {
try (InputStream stream = new FileInputStream(testFilePath)) {
doNothing().when(azureStorageClientSpy).uploadStream(any(InputStream.class), any(CloudBlockBlob.class));
@ -136,8 +133,7 @@ class AzureStorageClientTest {
}
@Test
void UploadStreamToBlob_CompressMode_CompressAndUploadStreamIsCalled()
throws IOException, URISyntaxException, StorageException {
void UploadStreamToBlob_CompressMode_CompressAndUploadStreamIsCalled() throws IOException, URISyntaxException, StorageException {
try (InputStream stream = new FileInputStream(testFilePath)) {
doNothing().when(azureStorageClientSpy)
.compressAndUploadStream(any(InputStream.class), any(CloudBlockBlob.class));
@ -247,4 +243,4 @@ class AzureStorageClientTest {
IllegalArgumentException.class,
() -> azureStorageClient.getBlobSize(null));
}
}
}

Просмотреть файл

@ -90,10 +90,12 @@ class E2ETest {
appKey = Files.readAllLines(Paths.get(secretPath)).get(0);
}
tableName = "JavaTest_" + new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss_SSS").format(Calendar.getInstance().getTime()) + "_" + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
tableName = "JavaTest_" + new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss_SSS").format(Calendar.getInstance().getTime()) + "_"
+ ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
principalFqn = String.format("aadapp=%s;%s", appId, tenantId);
ConnectionStringBuilder dmCsb = ConnectionStringBuilder.createWithAadApplicationCredentials(System.getenv("DM_CONNECTION_STRING"), appId, appKey, tenantId);
ConnectionStringBuilder dmCsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(System.getenv("DM_CONNECTION_STRING"), appId, appKey, tenantId);
dmCsb.setUserNameForTracing("testUser");
try {
ingestClient = IngestClientFactory.createClient(dmCsb);
@ -101,7 +103,8 @@ class E2ETest {
Assertions.fail("Failed to create ingest client", ex);
}
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
try {
streamingIngestClient = IngestClientFactory.createStreamingIngestClient(engineCsb);
queryClient = new ClientImpl(engineCsb);
@ -138,8 +141,13 @@ class E2ETest {
resourcesPath = Paths.get(System.getProperty("user.dir"), "src", "test", "resources").toString();
try {
String mappingAsString = new String(Files.readAllBytes(Paths.get(resourcesPath, "dataset_mapping.json")));
queryClient.executeToJsonResult(databaseName, String.format(".create table %s ingestion json mapping '%s' '%s'",
tableName, mappingReference, mappingAsString));
queryClient.executeToJsonResult(
databaseName,
String.format(
".create table %s ingestion json mapping '%s' '%s'",
tableName,
mappingReference,
mappingAsString));
} catch (Exception ex) {
Assertions.fail("Failed to create ingestion mapping", ex);
}
@ -168,7 +176,7 @@ class E2ETest {
first.setPath("$.rownumber");
ColumnMapping second = new ColumnMapping("rowguid", "string");
second.setPath("$.rowguid");
ColumnMapping[] columnMapping = new ColumnMapping[]{first, second};
ColumnMapping[] columnMapping = new ColumnMapping[] {first, second};
ingestionPropertiesWithColumnMapping.setIngestionMapping(columnMapping, IngestionMappingKind.JSON);
ingestionPropertiesWithColumnMapping.setDataFormat(DataFormat.JSON);
@ -263,7 +271,7 @@ class E2ETest {
boolean found = false;
try {
result = localQueryClient.execute(databaseName, String.format(".show database %s principals", databaseName));
//result = localQueryClient.execute(databaseName, String.format(".show version"));
// result = localQueryClient.execute(databaseName, String.format(".show version"));
} catch (Exception ex) {
Assertions.fail("Failed to execute show database principals command", ex);
}
@ -358,7 +366,8 @@ class E2ETest {
@Test
void testCreateWithUserPrompt() {
Assumptions.assumeTrue(IsManualExecution());
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithUserPrompt(System.getenv("ENGINE_CONNECTION_STRING"), null, System.getenv("USERNAME_HINT"));
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithUserPrompt(System.getenv("ENGINE_CONNECTION_STRING"), null, System.getenv("USERNAME_HINT"));
assertTrue(canAuthenticate(engineCsb));
}
@ -375,13 +384,15 @@ class E2ETest {
Assumptions.assumeTrue(StringUtils.isNotBlank(System.getenv("PRIVATE_PKCS8_FILE_LOC")));
X509Certificate cer = SecurityUtils.getPublicCertificate(System.getenv("PUBLIC_X509CER_FILE_LOC"));
PrivateKey privateKey = SecurityUtils.getPrivateKey(System.getenv("PRIVATE_PKCS8_FILE_LOC"));
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithAadApplicationCertificate(System.getenv("ENGINE_CONNECTION_STRING"), appId, cer, privateKey, "microsoft.onmicrosoft.com");
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithAadApplicationCertificate(System.getenv("ENGINE_CONNECTION_STRING"), appId, cer, privateKey, "microsoft.onmicrosoft.com");
assertTrue(canAuthenticate(engineCsb));
}
@Test
void testCreateWithAadApplicationCredentials() {
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
assertTrue(canAuthenticate(engineCsb));
}
@ -397,7 +408,8 @@ class E2ETest {
void testCreateWithAadTokenProviderAuthentication() {
Assumptions.assumeTrue(StringUtils.isNotBlank(System.getenv("TOKEN")));
Callable<String> tokenProviderCallable = () -> System.getenv("TOKEN");
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithAadTokenProviderAuthentication(System.getenv("ENGINE_CONNECTION_STRING"), tokenProviderCallable);
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithAadTokenProviderAuthentication(System.getenv("ENGINE_CONNECTION_STRING"), tokenProviderCallable);
assertTrue(canAuthenticate(engineCsb));
}
@ -447,7 +459,9 @@ class E2ETest {
crp.setParameter("xtextParam", "Two");
crp.setParameter("xtimeParam", new CslTimespanFormat("-00:00:02.0020002").getValue()); // Or can pass Duration
String query = String.format("declare query_parameters(xdoubleParam:real, xboolParam:bool, xint16Param:int, xint64Param:long, xdateParam:datetime, xtextParam:string, xtimeParam:time); %s | where xdouble == xdoubleParam and xbool == xboolParam and xint16 == xint16Param and xint64 == xint64Param and xdate == xdateParam and xtext == xtextParam and xtime == xtimeParam", tableName);
String query = String.format(
"declare query_parameters(xdoubleParam:real, xboolParam:bool, xint16Param:int, xint64Param:long, xdateParam:datetime, xtextParam:string, xtimeParam:time); %s | where xdouble == xdoubleParam and xbool == xboolParam and xint16 == xint16Param and xint64 == xint64Param and xdate == xdateParam and xtext == xtextParam and xtime == xtimeParam",
tableName);
KustoOperationResult resultObj = queryClient.execute(databaseName, query, crp);
KustoResultSetTable mainTableResult = resultObj.getPrimaryResults();
mainTableResult.next();
@ -466,7 +480,10 @@ class E2ETest {
KustoOperationResult resultObj = queryClient.execute(databaseName, query, clientRequestProperties);
stopWatch.stop();
long timeConvertedToJavaObj = stopWatch.getTime();
System.out.printf("Convert json to KustoOperationResult result count='%s' returned in '%s'ms%n", resultObj.getPrimaryResults().count(), timeConvertedToJavaObj);
System.out.printf(
"Convert json to KustoOperationResult result count='%s' returned in '%s'ms%n",
resultObj.getPrimaryResults().count(),
timeConvertedToJavaObj);
// Specialized use case - API returns raw json for performance
stopWatch.reset();
@ -477,14 +494,14 @@ class E2ETest {
System.out.printf("Raw json result size='%s' returned in '%s'ms%n", jsonResult.length(), timeRawJson);
// Depends on many transient factors, but is ~15% cheaper when there are many records
//assertTrue(timeRawJson < timeConvertedToJavaObj);
// assertTrue(timeRawJson < timeConvertedToJavaObj);
// Specialized use case - API streams raw json for performance
stopWatch.reset();
stopWatch.start();
// The InputStream *must* be closed by the caller to prevent memory leaks
try (InputStream is = queryClient.executeStreamingQuery(databaseName, query, clientRequestProperties);
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
StringBuilder streamedResult = new StringBuilder();
char[] buffer = new char[65536];
String streamedLine;
@ -508,7 +525,8 @@ class E2ETest {
@Test
void testSameHttpClientInstance() throws DataClientException, DataServiceException, URISyntaxException, IOException {
ConnectionStringBuilder engineCsb = ConnectionStringBuilder.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
ConnectionStringBuilder engineCsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(System.getenv("ENGINE_CONNECTION_STRING"), appId, appKey, tenantId);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpClient httpClientSpy = Mockito.spy(httpClient);
ClientImpl clientImpl = new ClientImpl(engineCsb, httpClientSpy);

Просмотреть файл

@ -71,13 +71,10 @@ class ManagedStreamingIngestClientTest {
private static IngestionProperties ingestionProperties;
private static final String STORAGE_URL = "https://testcontosourl.com/storageUrl";
@Mock
private static StreamingClient streamingClientMock;
@Mock private static StreamingClient streamingClientMock;
@Captor
private static ArgumentCaptor<InputStream> argumentCaptor;
@Captor
private static ArgumentCaptor<ClientRequestProperties> clientRequestPropertiesCaptor;
@Captor private static ArgumentCaptor<InputStream> argumentCaptor;
@Captor private static ArgumentCaptor<ClientRequestProperties> clientRequestPropertiesCaptor;
private static final UUID CustomUUID = UUID.fromString("11111111-1111-1111-1111-111111111111");
@ -119,7 +116,10 @@ class ManagedStreamingIngestClientTest {
retryTemplate.sleepBaseSecs = 0;
retryTemplate.maxJitterSecs = 0;
managedStreamingIngestClient = new ManagedStreamingIngestClient(resourceManagerMock, azureStorageClientMock, streamingClientMock,
managedStreamingIngestClient = new ManagedStreamingIngestClient(
resourceManagerMock,
azureStorageClientMock,
streamingClientMock,
retryTemplate);
ingestionProperties = new IngestionProperties("dbName", "tableName");
ingestionProperties.setIngestionMapping("mappingName", IngestionMapping.IngestionMappingKind.JSON);
@ -160,7 +160,9 @@ class ManagedStreamingIngestClientTest {
@Test
void IngestFromBlob_IngestionReportMethodIsTable_RemovesSecrets() throws Exception {
BlobSourceInfo blobSourceInfo = new BlobSourceInfo("https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud", 100);
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(
"https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud",
100);
ingestionProperties.setReportMethod(IngestionProperties.IngestionReportMethod.TABLE);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
ArgumentCaptor<TableServiceEntity> capture = ArgumentCaptor.forClass(TableServiceEntity.class);
@ -224,7 +226,7 @@ class ManagedStreamingIngestClientTest {
() -> managedStreamingIngestClient.ingestFromResultSet(null, ingestionProperties));
}
//Since, like streamingClient, managedStreamingClient forwards everything to the IngestFromStream methods we can use similar tests
// Since, like streamingClient, managedStreamingClient forwards everything to the IngestFromStream methods we can use similar tests
@ParameterizedTest
@ValueSource(booleans = {true, false})
void IngestFromFile_Csv(boolean useSourceId) throws Exception {
@ -235,8 +237,14 @@ class ManagedStreamingIngestClientTest {
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length(), sourceId);
OperationStatus status = managedStreamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
verifyClientRequestId(0, sourceId);
}
@ -260,10 +268,18 @@ class ManagedStreamingIngestClientTest {
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.CSV);
ingestionProperties.setIngestionMapping("mappingName", IngestionMapping.IngestionMappingKind.CSV);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet, sourceId);
OperationStatus status = managedStreamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
OperationStatus status = managedStreamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, "Name,Age,Weight");
@ -281,8 +297,14 @@ class ManagedStreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status = managedStreamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), any(String.class), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
any(String.class),
any(boolean.class));
verifyCompressedStreamContent(argumentCaptor.getValue(), contents);
verifyClientRequestId();
}
@ -298,12 +320,19 @@ class ManagedStreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status;
try {
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), any(String.class), any(boolean.class))).then(a -> {
verifyCompressedStreamContent(argumentCaptor.getValue(), jsonDataUncompressed);
visited.set(true);
return null;
});
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
any(String.class),
any(boolean.class))).then(a -> {
verifyCompressedStreamContent(argumentCaptor.getValue(), jsonDataUncompressed);
visited.set(true);
return null;
});
status = managedStreamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
} finally {
@ -322,14 +351,23 @@ class ManagedStreamingIngestClientTest {
InputStream inputStream = new CloseableByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
UUID sourceId = useSourceId ? CustomUUID : null;
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream, leaveOpen, sourceId);
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
/* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed.
* When the given stream content is already compressed, the user must specify that in the stream source info.
* This method verifies if the stream was compressed correctly.
/*
* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed. When the given
* stream content is already compressed, the user must specify that in the stream source info. This method verifies if the stream was compressed
* correctly.
*/
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -354,12 +392,19 @@ class ManagedStreamingIngestClientTest {
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
any(ClientRequestProperties.class), any(String.class), eq("JsonMapping"), any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
});
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
any(ClientRequestProperties.class),
any(String.class),
eq("JsonMapping"),
any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
});
// Should fail 3 times and then succeed with the queued client
managedStreamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties);
@ -378,12 +423,19 @@ class ManagedStreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
any(ClientRequestProperties.class), any(String.class), eq("mappingName"), any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
});
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
any(ClientRequestProperties.class),
any(String.class),
eq("mappingName"),
any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
});
// Should fail 3 times and then succeed with the queued client
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
@ -405,24 +457,41 @@ class ManagedStreamingIngestClientTest {
UUID sourceId = useSourceId ? CustomUUID : null;
try {
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
any(ClientRequestProperties.class), any(String.class), eq("mappingName"), any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
}).thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
}).thenReturn(null);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
any(ClientRequestProperties.class),
any(String.class),
eq("mappingName"),
any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
})
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", false);
})
.thenReturn(null);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream, leaveOpen, sourceId);
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
assertEquals(failCount, times[0]);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
verifyClientRequestId(2, sourceId);
@ -448,30 +517,49 @@ class ManagedStreamingIngestClientTest {
final int[] times = {0};
String data = "Name, Age, Weight, Height";
InputStream inputStream = new CloseableByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
DataWebException ex = new DataWebException("{\"error\" : {\n" +
" \"code\": \"A\", \"message\": \"B\", \"@message\": \"C\", \"@type\": \"D\", \"@context\": {}, \n" +
" \"@permanent\": false\n" +
"} }", null);
DataWebException ex = new DataWebException(
"{\"error\" : {\n" +
" \"code\": \"A\", \"message\": \"B\", \"@message\": \"C\", \"@type\": \"D\", \"@context\": {}, \n" +
" \"@permanent\": false\n" +
"} }",
null);
UUID sourceId = useSourceId ? CustomUUID : null;
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
any(ClientRequestProperties.class), any(String.class), eq("mappingName"), any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", ex, false);
}).thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", ex, false);
}).thenReturn(null);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
any(ClientRequestProperties.class),
any(String.class),
eq("mappingName"),
any(boolean.class)))
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", ex, false);
})
.thenAnswer((a) -> {
times[0]++;
throw new DataServiceException("some cluster", "Some error", ex, false);
})
.thenReturn(null);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream, leaveOpen, sourceId);
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
OperationStatus status = managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
assertEquals(failCount, times[0]);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
verifyClientRequestId(2, sourceId);
@ -493,18 +581,29 @@ class ManagedStreamingIngestClientTest {
// It's an array, so we can safely modify it in the lambda
String data = "Name, Age, Weight, Height";
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
DataWebException ex = new DataWebException("{\"error\" : {\n" +
" \"code\": \"A\", \"message\": \"B\", \"@message\": \"C\", \"@type\": \"D\", \"@context\": {}, \n" +
" \"@permanent\": true\n" +
"} }", null);
DataWebException ex = new DataWebException(
"{\"error\" : {\n" +
" \"code\": \"A\", \"message\": \"B\", \"@message\": \"C\", \"@type\": \"D\", \"@context\": {}, \n" +
" \"@permanent\": true\n" +
"} }",
null);
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
any(ClientRequestProperties.class), any(String.class), eq("mappingName"), any(boolean.class)))
.thenAnswer((a) -> {
throw new DataServiceException("some cluster", "Some error", ex, true);
}).thenAnswer((a) -> {
throw new DataServiceException("some cluster", "Some error", ex, true);
}).thenReturn(null);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
any(ClientRequestProperties.class),
any(String.class),
eq("mappingName"),
any(boolean.class)))
.thenAnswer((a) -> {
throw new DataServiceException("some cluster", "Some error", ex, true);
})
.thenAnswer((a) -> {
throw new DataServiceException("some cluster", "Some error", ex, true);
})
.thenReturn(null);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
assertThrows(IngestionServiceException.class, () -> managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties));
@ -531,8 +630,14 @@ class ManagedStreamingIngestClientTest {
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream, leaveOpen, sourceId);
managedStreamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties);
verify(streamingClientMock, never()).executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
clientRequestPropertiesCaptor.capture(), any(String.class), eq("mappingName"), any(boolean.class));
verify(streamingClientMock, never()).executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
clientRequestPropertiesCaptor.capture(),
any(String.class),
eq("mappingName"),
any(boolean.class));
verify(azureStorageClientMock, atLeast(1)).uploadStreamToBlob(capture.capture(), anyString(), anyString(), anyBoolean());
@ -548,8 +653,8 @@ class ManagedStreamingIngestClientTest {
@Test
void CreateManagedStreamingIngestClient_WithDmUri_Pass() throws URISyntaxException {
ManagedStreamingIngestClient client =
ManagedStreamingIngestClient.fromDmConnectionString(ConnectionStringBuilder.createWithUserPrompt("https://ingest-testendpoint.dev.kusto.windows.net"));
ManagedStreamingIngestClient client = ManagedStreamingIngestClient
.fromDmConnectionString(ConnectionStringBuilder.createWithUserPrompt("https://ingest-testendpoint.dev.kusto.windows.net"));
assertNotNull(client);
assertEquals("https://ingest-testendpoint.dev.kusto.windows.net", client.queuedIngestClient.connectionDataSource);
assertEquals("https://testendpoint.dev.kusto.windows.net", client.streamingIngestClient.connectionDataSource);
@ -558,16 +663,15 @@ class ManagedStreamingIngestClientTest {
@Test
void CreateManagedStreamingIngestClient_WithWrongDmUri_Fail() {
assertThrows(IllegalArgumentException.class, () -> {
ManagedStreamingIngestClient client =
ManagedStreamingIngestClient.fromDmConnectionString(ConnectionStringBuilder.createWithUserPrompt("https://testendpoint.dev.kusto.windows.net"));
ManagedStreamingIngestClient client = ManagedStreamingIngestClient
.fromDmConnectionString(ConnectionStringBuilder.createWithUserPrompt("https://testendpoint.dev.kusto.windows.net"));
});
}
@Test
void CreateManagedStreamingIngestClient_WithEngineUri_Pass() throws URISyntaxException {
ManagedStreamingIngestClient client =
ManagedStreamingIngestClient.fromEngineConnectionString(
ConnectionStringBuilder.createWithUserPrompt("https://testendpoint.dev.kusto.windows.net"));
ManagedStreamingIngestClient client = ManagedStreamingIngestClient.fromEngineConnectionString(
ConnectionStringBuilder.createWithUserPrompt("https://testendpoint.dev.kusto.windows.net"));
assertNotNull(client);
assertEquals("https://ingest-testendpoint.dev.kusto.windows.net", client.queuedIngestClient.connectionDataSource);
assertEquals("https://testendpoint.dev.kusto.windows.net", client.streamingIngestClient.connectionDataSource);
@ -576,13 +680,11 @@ class ManagedStreamingIngestClientTest {
@Test
void CreateManagedStreamingIngestClient_WithWrongEngineUri_Fail() {
assertThrows(IllegalArgumentException.class, () -> {
ManagedStreamingIngestClient client =
ManagedStreamingIngestClient.fromEngineConnectionString(
ConnectionStringBuilder.createWithUserPrompt("https://ingest-testendpoint.dev.kusto.windows.net"));
ManagedStreamingIngestClient client = ManagedStreamingIngestClient.fromEngineConnectionString(
ConnectionStringBuilder.createWithUserPrompt("https://ingest-testendpoint.dev.kusto.windows.net"));
});
}
private static void verifyClientRequestId() {
verifyClientRequestId(0, null);
}
@ -601,4 +703,4 @@ class ManagedStreamingIngestClientTest {
});
assertDoesNotThrow(() -> assertEquals(Integer.parseInt(values[2]), count));
}
}
}

Просмотреть файл

@ -134,7 +134,9 @@ class QueuedIngestClientTest {
@Test
void IngestFromBlob_IngestionReportMethodIsTable_RemovesSecrets() throws Exception {
BlobSourceInfo blobSourceInfo = new BlobSourceInfo("https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud", 100);
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(
"https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud",
100);
ingestionProperties.setReportMethod(IngestionProperties.IngestionReportMethod.TABLE);
ArgumentCaptor<TableServiceEntity> captor = ArgumentCaptor.forClass(TableServiceEntity.class);
@ -146,19 +148,21 @@ class QueuedIngestClientTest {
@Test
void IngestFromBlob_IngestionIgnoreFirstRecord_SetsProperty() throws Exception {
BlobSourceInfo blobSourceInfo = new BlobSourceInfo("https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud", 100);
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(
"https://storage.table.core.windows.net/ingestionsstatus20190505?sv=2018-03-28&tn=ingestionsstatus20190505&sig=anAusomeSecret%2FK024xNydFzT%2B2cCE%2BA2S8Y6U%3D&st=2019-05-05T09%3A00%3A31Z&se=2019-05-09T10%3A00%3A31Z&sp=raud",
100);
ingestionProperties.setIgnoreFirstRecord(true);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
queuedIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties);
verify(azureStorageClientMock, atLeast(1)).postMessageToQueue(anyString(), captor.capture());
assertTrue ((captor.getValue()).contains("\"ignoreFirstRecord\":\"true\""));
assertTrue((captor.getValue()).contains("\"ignoreFirstRecord\":\"true\""));
ingestionProperties.setIgnoreFirstRecord(false);
queuedIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties);
verify(azureStorageClientMock, atLeast(1)).postMessageToQueue(anyString(), captor.capture());
assertTrue ((captor.getValue()).contains("\"ignoreFirstRecord\":\"false\""));
assertTrue((captor.getValue()).contains("\"ignoreFirstRecord\":\"false\""));
}
@Test
@ -181,7 +185,8 @@ class QueuedIngestClientTest {
.contains(
"\"validationPolicy\":{\"validationOptions\":\"DoNotValidate\",\"validationPolicyType\":\"BestEffort\"}"));
ingestionProperties.setValidationPolicy(new ValidationPolicy(ValidationPolicy.ValidationOptions.VALIDATE_CSV_INPUT_COLUMN_LEVEL_ONLY, ValidationPolicy.ValidationImplications.FAIL));
ingestionProperties.setValidationPolicy(
new ValidationPolicy(ValidationPolicy.ValidationOptions.VALIDATE_CSV_INPUT_COLUMN_LEVEL_ONLY, ValidationPolicy.ValidationImplications.FAIL));
queuedIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties);
verify(azureStorageClientMock, atLeast(1)).postMessageToQueue(anyString(), captor.capture());
assertTrue(
@ -345,8 +350,11 @@ class QueuedIngestClientTest {
queuedIngestClient.setConnectionDataSource("https://testendpoint.dev.kusto.windows.net");
FileSourceInfo fileSourceInfo = new FileSourceInfo(testFilePath, 100);
String expectedMessage =
String.format(WRONG_ENDPOINT_MESSAGE + ": '%s'", EXPECTED_SERVICE_TYPE, ENDPOINT_SERVICE_TYPE_ENGINE, "https://ingest-testendpoint.dev.kusto.windows.net");
String expectedMessage = String.format(
WRONG_ENDPOINT_MESSAGE + ": '%s'",
EXPECTED_SERVICE_TYPE,
ENDPOINT_SERVICE_TYPE_ENGINE,
"https://ingest-testendpoint.dev.kusto.windows.net");
Exception exception = assertThrows(IngestionClientException.class, () -> queuedIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties));
assertEquals(expectedMessage, exception.getMessage());
}
@ -359,16 +367,15 @@ class QueuedIngestClientTest {
}
final Holder holder = new Holder();
holder.name = "fileName";
BiFunction<DataFormat, CompressionType, String> genName =
(DataFormat format, CompressionType compression) -> {
boolean shouldCompress = IngestClientBase.shouldCompress(compression, format);
return ingestClient.genBlobName(
holder.name,
"db1",
"t1",
format.getKustoValue(),
shouldCompress ? CompressionType.gz : compression);
};
BiFunction<DataFormat, CompressionType, String> genName = (DataFormat format, CompressionType compression) -> {
boolean shouldCompress = IngestClientBase.shouldCompress(compression, format);
return ingestClient.genBlobName(
holder.name,
"db1",
"t1",
format.getKustoValue(),
shouldCompress ? CompressionType.gz : compression);
};
String csvNoCompression = genName.apply(DataFormat.CSV, null);
assert (csvNoCompression.endsWith(".csv.gz"));
@ -396,7 +403,7 @@ class QueuedIngestClientTest {
Connection connection = DriverManager.getConnection("jdbc:sqlite:");
Statement statement = connection.createStatement();
statement.setQueryTimeout(5); // set timeout to 5 sec.
statement.setQueryTimeout(5); // set timeout to 5 sec.
statement.executeUpdate("drop table if exists person");
statement.executeUpdate("create table person (id integer, name string)");
@ -407,8 +414,6 @@ class QueuedIngestClientTest {
}
private String getSampleResultSetDump() {
return System.getProperty("line.separator").equals("\n") ?
"1,leo\n2,yui\n" :
"1,leo\r\n2,yui\r\n";
return System.getProperty("line.separator").equals("\n") ? "1,leo\n2,yui\n" : "1,leo\r\n2,yui\r\n";
}
}

Просмотреть файл

@ -56,8 +56,7 @@ class ResourceManagerTest {
}
@Test
void GetIngestionResource_TempStorage_VerifyRoundRobin()
throws IngestionServiceException, IngestionClientException {
void GetIngestionResource_TempStorage_VerifyRoundRobin() throws IngestionServiceException, IngestionClientException {
List<String> availableStorages = new ArrayList<>(Arrays.asList(STORAGE_1, STORAGE_2));
String storage = resourceManager.getIngestionResource(ResourceManager.ResourceType.TEMP_STORAGE);
@ -72,8 +71,7 @@ class ResourceManagerTest {
}
@Test
void GetIngestionResource_AggregationQueue_VerifyRoundRobin()
throws IngestionServiceException, IngestionClientException {
void GetIngestionResource_AggregationQueue_VerifyRoundRobin() throws IngestionServiceException, IngestionClientException {
List<String> availableQueues = new ArrayList<>(Arrays.asList(QUEUE_1, QUEUE_2));
String queue = resourceManager
@ -90,24 +88,21 @@ class ResourceManagerTest {
}
@Test
void GetIngestionResource_StatusTable_ReturnCorrectTable()
throws IngestionServiceException, IngestionClientException {
void GetIngestionResource_StatusTable_ReturnCorrectTable() throws IngestionServiceException, IngestionClientException {
assertEquals(
STATUS_TABLE,
resourceManager.getIngestionResource(ResourceManager.ResourceType.INGESTIONS_STATUS_TABLE));
}
@Test
void GetIngestionResource_FailedIngestionQueue_ReturnCorrectQueue()
throws IngestionServiceException, IngestionClientException {
void GetIngestionResource_FailedIngestionQueue_ReturnCorrectQueue() throws IngestionServiceException, IngestionClientException {
assertEquals(
FAILED_QUEUE,
resourceManager.getIngestionResource(ResourceManager.ResourceType.FAILED_INGESTIONS_QUEUE));
}
@Test
void GetIngestionResource_SuccessfulIngestionQueue_ReturnCorrectQueue()
throws IngestionServiceException, IngestionClientException {
void GetIngestionResource_SuccessfulIngestionQueue_ReturnCorrectQueue() throws IngestionServiceException, IngestionClientException {
assertEquals(
SUCCESS_QUEUE,
resourceManager.getIngestionResource(ResourceManager.ResourceType.SUCCESSFUL_INGESTIONS_QUEUE));
@ -161,9 +156,10 @@ class ResourceManagerTest {
valuesList.add(new ArrayList<>((Collections.singletonList(AUTH_TOKEN))));
String listAsJson = new ObjectMapper().writeValueAsString(valuesList);
String response = "{\"Tables\":[{\"TableName\":\"Table_0\",\"Columns\":[{\"ColumnName\":\"AuthorizationContext\",\"DataType\":\"String\",\"ColumnType\":\"string\"}],\"Rows\":" +
String response = "{\"Tables\":[{\"TableName\":\"Table_0\",\"Columns\":[{\"ColumnName\":\"AuthorizationContext\",\"DataType\":\"String\",\"ColumnType\":\"string\"}],\"Rows\":"
+
listAsJson + "}]}";
return new KustoOperationResult(response, "v1");
}
}
}

Просмотреть файл

@ -64,11 +64,9 @@ class StreamingIngestClientTest {
private static StreamingIngestClient streamingIngestClient;
private IngestionProperties ingestionProperties;
@Mock
private static StreamingClient streamingClientMock;
@Mock private static StreamingClient streamingClientMock;
@Captor
private static ArgumentCaptor<InputStream> argumentCaptor;
@Captor private static ArgumentCaptor<InputStream> argumentCaptor;
private static final String ENDPOINT_SERVICE_TYPE_DM = "DataManagement";
private String resourcesDirectory = System.getProperty("user.dir") + "/src/test/resources/";
@ -83,11 +81,25 @@ class StreamingIngestClientTest {
@BeforeEach
void setUpEach() throws Exception {
ingestionProperties = new IngestionProperties("dbName", "tableName");
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), any(String.class), any(boolean.class))).thenReturn(null);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
any(String.class),
any(boolean.class))).thenReturn(null);
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), isNull(), any(boolean.class))).thenReturn(null);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
isNull(),
any(boolean.class))).thenReturn(null);
}
@Test
@ -97,12 +109,19 @@ class StreamingIngestClientTest {
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
isNull(),
any(boolean.class));
/* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed.
* When the given stream content is already compressed, the user must specify that in the stream source info.
* This method verifies if the stream was compressed correctly.
/*
* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed. When the given
* stream content is already compressed, the user must specify that in the stream source info. This method verifies if the stream was compressed
* correctly.
*/
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -114,15 +133,24 @@ class StreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
String clientRequestId = "clientRequestId";
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties, clientRequestId).getIngestionStatusCollection().get(0).status;
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties, clientRequestId)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
ArgumentCaptor<ClientRequestProperties> clientRequestPropertiesArgumentCaptor = ArgumentCaptor.forClass(ClientRequestProperties.class);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
clientRequestPropertiesArgumentCaptor.capture(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
clientRequestPropertiesArgumentCaptor.capture(),
any(String.class),
isNull(),
any(boolean.class));
/* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed.
* When the given stream content is already compressed, the user must specify that in the stream source info.
* This method verifies if the stream was compressed correctly.
/*
* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed. When the given
* stream content is already compressed, the user must specify that in the stream source info. This method verifies if the stream was compressed
* correctly.
*/
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -145,8 +173,14 @@ class StreamingIngestClientTest {
streamSourceInfo.setCompressionType(CompressionType.gz);
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
isNull(),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -161,8 +195,14 @@ class StreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), any(String.class), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
any(String.class),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -184,8 +224,14 @@ class StreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), any(String.class), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
any(String.class),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, data);
@ -193,7 +239,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromStream_NullStreamSourceInfo_IllegalArgumentException() {
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(null, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -203,7 +250,8 @@ class StreamingIngestClientTest {
String data = "Name, Age, Weight, Height";
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, null),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -214,7 +262,8 @@ class StreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties = new IngestionProperties(null, "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -225,7 +274,8 @@ class StreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties = new IngestionProperties("", "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -236,7 +286,8 @@ class StreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties = new IngestionProperties("database", null);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -247,7 +298,8 @@ class StreamingIngestClientTest {
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties = new IngestionProperties("database", "");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -271,7 +323,8 @@ class StreamingIngestClientTest {
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
ingestionProperties.setIngestionMapping("CsvMapping", IngestionMapping.IngestionMappingKind.CSV);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Wrong ingestion mapping for format 'json'; mapping kind should be 'Json', but was 'Csv'."));
@ -294,7 +347,8 @@ class StreamingIngestClientTest {
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.AVRO);
ingestionProperties.setIngestionMapping("CsvMapping", IngestionMapping.IngestionMappingKind.CSV);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Wrong ingestion mapping for format 'avro'; mapping kind should be 'Avro', but was 'Csv'."));
@ -304,7 +358,8 @@ class StreamingIngestClientTest {
void IngestFromStream_EmptyStream_IngestionClientException() {
InputStream inputStream = new ByteArrayInputStream(new byte[0]);
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Empty stream."));
@ -312,26 +367,42 @@ class StreamingIngestClientTest {
@Test
void IngestFromStream_CaughtDataClientException_IngestionClientException() throws Exception {
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), isNull(), any(boolean.class))).thenThrow(DataClientException.class);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
isNull(),
any(boolean.class))).thenThrow(DataClientException.class);
String data = "Name, Age, Weight, Height";
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
assertThrows(IngestionClientException.class,
assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@Test
void IngestFromStream_CaughtDataServiceException_IngestionServiceException() throws Exception {
when(streamingClientMock.executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), isNull(), any(boolean.class))).thenThrow(DataServiceException.class);
when(
streamingClientMock.executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
isNull(),
any(boolean.class))).thenThrow(DataServiceException.class);
String data = "Name, Age, Weight, Height";
InputStream inputStream = new ByteArrayInputStream(StandardCharsets.UTF_8.encode(data).array());
StreamSourceInfo streamSourceInfo = new StreamSourceInfo(inputStream);
assertThrows(IngestionServiceException.class,
assertThrows(
IngestionServiceException.class,
() -> streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -342,23 +413,42 @@ class StreamingIngestClientTest {
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
OperationStatus status = streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
isNull(),
any(boolean.class));
}
@Test
void IngestFromFile_GivenStreamingIngestClientAndDmEndpoint_ThrowsIngestionClientException() throws Exception {
DataServiceException dataClientException = new DataServiceException("some cluster", "Error in post request. status 404",
DataServiceException dataClientException = new DataServiceException(
"some cluster",
"Error in post request. status 404",
new DataWebException("Error in post request", new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 404, "Not found"))),
true);
doThrow(dataClientException).when(streamingClientMock).executeStreamingIngest(eq(ingestionProperties.getDatabaseName()), eq(ingestionProperties.getTableName()), any(), isNull(), any(), isNull(), eq(false));
when(streamingClientMock.execute(Commands.VERSION_SHOW_COMMAND)).thenReturn(new KustoOperationResult("{\"Tables\":[{\"TableName\":\"Table_0\",\"Columns\":[{\"ColumnName\":\"BuildVersion\",\"DataType\":\"String\"},{\"ColumnName\":\"BuildTime\",\"DataType\":\"DateTime\"},{\"ColumnName\":\"ServiceType\",\"DataType\":\"String\"},{\"ColumnName\":\"ProductVersion\",\"DataType\":\"String\"}],\"Rows\":[[\"1.0.0.0\",\"2000-01-01T00:00:00Z\",\"DataManagement\",\"PrivateBuild.yischoen.YISCHOEN-OP7070.2020-09-07 12-09-22\"]]}]}", "v1"));
doThrow(dataClientException).when(streamingClientMock)
.executeStreamingIngest(
eq(ingestionProperties.getDatabaseName()),
eq(ingestionProperties.getTableName()),
any(),
isNull(),
any(),
isNull(),
eq(false));
when(streamingClientMock.execute(Commands.VERSION_SHOW_COMMAND)).thenReturn(
new KustoOperationResult(
"{\"Tables\":[{\"TableName\":\"Table_0\",\"Columns\":[{\"ColumnName\":\"BuildVersion\",\"DataType\":\"String\"},{\"ColumnName\":\"BuildTime\",\"DataType\":\"DateTime\"},{\"ColumnName\":\"ServiceType\",\"DataType\":\"String\"},{\"ColumnName\":\"ProductVersion\",\"DataType\":\"String\"}],\"Rows\":[[\"1.0.0.0\",\"2000-01-01T00:00:00Z\",\"DataManagement\",\"PrivateBuild.yischoen.YISCHOEN-OP7070.2020-09-07 12-09-22\"]]}]}",
"v1"));
streamingIngestClient.setConnectionDataSource("https://ingest-testendpoint.dev.kusto.windows.net");
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
String expectedMessage =
String.format(WRONG_ENDPOINT_MESSAGE + ": '%s'", EXPECTED_SERVICE_TYPE, ENDPOINT_SERVICE_TYPE_DM, "https://testendpoint.dev.kusto.windows.net");
String expectedMessage = String
.format(WRONG_ENDPOINT_MESSAGE + ": '%s'", EXPECTED_SERVICE_TYPE, ENDPOINT_SERVICE_TYPE_DM, "https://testendpoint.dev.kusto.windows.net");
Exception exception = assertThrows(IngestionClientException.class, () -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties));
assertEquals(expectedMessage, exception.getMessage());
}
@ -373,8 +463,14 @@ class StreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status = streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), any(String.class), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
any(String.class),
any(boolean.class));
verifyCompressedStreamContent(argumentCaptor.getValue(), contents);
}
@ -387,15 +483,22 @@ class StreamingIngestClientTest {
ingestionProperties.setIngestionMapping("JsonMapping", IngestionMapping.IngestionMappingKind.JSON);
OperationStatus status = streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), any(String.class), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
any(String.class),
any(boolean.class));
verifyCompressedStreamContent(argumentCaptor.getValue(), jsonDataUncompressed);
}
@Test
void IngestFromFile_NullFileSourceInfo_IllegalArgumentException() {
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(null, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -403,7 +506,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromFile_FileSourceInfoWithNullFilePath_IllegalArgumentException() {
FileSourceInfo fileSourceInfo1 = new FileSourceInfo(null, 0);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo1, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -411,7 +515,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromFile_FileSourceInfoWithBlankFilePath_IllegalArgumentException() {
FileSourceInfo fileSourceInfo2 = new FileSourceInfo("", 0);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo2, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -420,7 +525,8 @@ class StreamingIngestClientTest {
void IngestFromFile_NullIngestionProperties_IllegalArgumentException() {
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, null),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -430,7 +536,8 @@ class StreamingIngestClientTest {
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties = new IngestionProperties(null, "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -440,7 +547,8 @@ class StreamingIngestClientTest {
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties = new IngestionProperties("", "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -450,7 +558,8 @@ class StreamingIngestClientTest {
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties = new IngestionProperties("database", null);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -460,7 +569,8 @@ class StreamingIngestClientTest {
String path = resourcesDirectory + "testdata.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties = new IngestionProperties("database", "");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -482,7 +592,8 @@ class StreamingIngestClientTest {
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
ingestionProperties.setIngestionMapping("CsvMapping", IngestionMapping.IngestionMappingKind.CSV);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Wrong ingestion mapping for format 'json'; mapping kind should be 'Json', but was 'Csv'."));
@ -501,7 +612,8 @@ class StreamingIngestClientTest {
void IngestFromFile_EmptyFile_IngestionClientException() {
String path = resourcesDirectory + "empty.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Empty file."));
@ -523,15 +635,24 @@ class StreamingIngestClientTest {
when(cloudBlockBlob.getProperties()).thenReturn(blobProperties);
when(cloudBlockBlob.openInputStream()).thenReturn(blobInputStream);
OperationStatus status = streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties, cloudBlockBlob).getIngestionStatusCollection().get(0).status;
OperationStatus status = streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties, cloudBlockBlob)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), any(InputStream.class),
isNull(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
any(InputStream.class),
isNull(),
any(String.class),
isNull(),
any(boolean.class));
}
@Test
void IngestFromBlob_NullBlobSourceInfo_IllegalArgumentException() {
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(null, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -539,7 +660,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromBlob_BlobSourceInfoWithNullBlobPath_IllegalArgumentException() {
BlobSourceInfo blobSourceInfo1 = new BlobSourceInfo(null);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo1, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -547,7 +669,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromBlob_BlobSourceInfoWithBlankBlobPath_IllegalArgumentException() {
BlobSourceInfo blobSourceInfo2 = new BlobSourceInfo("");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo2, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -556,7 +679,8 @@ class StreamingIngestClientTest {
void IngestFromBlob_NullIngestionProperties_IllegalArgumentException() {
String path = "blobPath";
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(path);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, null),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -566,7 +690,8 @@ class StreamingIngestClientTest {
String path = "blobPath";
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(path);
ingestionProperties = new IngestionProperties(null, "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -576,7 +701,8 @@ class StreamingIngestClientTest {
String path = "blobPath";
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(path);
ingestionProperties = new IngestionProperties("", "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -586,7 +712,8 @@ class StreamingIngestClientTest {
String path = "blobPath";
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(path);
ingestionProperties = new IngestionProperties("database", null);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -596,7 +723,8 @@ class StreamingIngestClientTest {
String path = "blobPath";
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(path);
ingestionProperties = new IngestionProperties("database", "");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -605,7 +733,8 @@ class StreamingIngestClientTest {
void IngestFromBlob_InvalidBlobPath_IngestionClientException() {
String path = "wrongURI";
BlobSourceInfo blobSourceInfo1 = new BlobSourceInfo(path);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo1, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
@ -617,7 +746,8 @@ class StreamingIngestClientTest {
String path = "https://storageaccount.blob.core.windows.net/container/blob.csv";
BlobSourceInfo blobSourceInfo2 = new BlobSourceInfo(path);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo2, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Unexpected Storage error when ingesting a blob."));
@ -635,7 +765,8 @@ class StreamingIngestClientTest {
doNothing().when(cloudBlockBlob).downloadAttributes();
when(cloudBlockBlob.getProperties()).thenReturn(blobProperties);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromBlob(blobSourceInfo, ingestionProperties, cloudBlockBlob),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Empty blob."));
@ -657,10 +788,18 @@ class StreamingIngestClientTest {
ArgumentCaptor<InputStream> argumentCaptor = ArgumentCaptor.forClass(InputStream.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
OperationStatus status = streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
OperationStatus status = streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties)
.getIngestionStatusCollection()
.get(0).status;
assertEquals(OperationStatus.Succeeded, status);
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(any(String.class), any(String.class), argumentCaptor.capture(),
isNull(), any(String.class), isNull(), any(boolean.class));
verify(streamingClientMock, atLeastOnce()).executeStreamingIngest(
any(String.class),
any(String.class),
argumentCaptor.capture(),
isNull(),
any(String.class),
isNull(),
any(boolean.class));
InputStream stream = argumentCaptor.getValue();
verifyCompressedStreamContent(stream, "Name,Age,Weight");
@ -668,7 +807,8 @@ class StreamingIngestClientTest {
@Test
void IngestFromResultSet_NullResultSetSourceInfo_IllegalArgumentException() {
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(null, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -677,7 +817,8 @@ class StreamingIngestClientTest {
void IngestFromResultSet_NullIngestionProperties_IllegalArgumentException() {
ResultSet resultSet = mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, null),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -687,7 +828,8 @@ class StreamingIngestClientTest {
ResultSet resultSet = mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
ingestionProperties = new IngestionProperties(null, "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -697,7 +839,8 @@ class StreamingIngestClientTest {
ResultSet resultSet = mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
ingestionProperties = new IngestionProperties("", "table");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -707,7 +850,8 @@ class StreamingIngestClientTest {
ResultSet resultSet = mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
ingestionProperties = new IngestionProperties("database", null);
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -717,7 +861,8 @@ class StreamingIngestClientTest {
ResultSet resultSet = mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
ingestionProperties = new IngestionProperties("database", "");
assertThrows(IllegalArgumentException.class,
assertThrows(
IllegalArgumentException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties),
"Expected IllegalArgumentException to be thrown, but it didn't");
}
@ -731,7 +876,8 @@ class StreamingIngestClientTest {
when(resultSetMetaData.getColumnCount()).thenReturn(0);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(resultSet);
IngestionClientException ingestionClientException = assertThrows(IngestionClientException.class,
IngestionClientException ingestionClientException = assertThrows(
IngestionClientException.class,
() -> streamingIngestClient.ingestFromResultSet(resultSetSourceInfo, ingestionProperties),
"Expected IngestionClientException to be thrown, but it didn't");
assertTrue(ingestionClientException.getMessage().contains("Empty ResultSet."));

Просмотреть файл

@ -10,4 +10,4 @@ public class TestDataItem {
public IngestionProperties ingestionProperties;
public int rows;
public boolean testOnstreamingIngestion = true;
}
}

Просмотреть файл

@ -21,10 +21,10 @@ class ResultSetSourceInfoTest {
ResultSet mockResultSet = Mockito.mock(ResultSet.class);
ResultSetSourceInfo resultSetSourceInfo = new ResultSetSourceInfo(mockResultSet);
//this also tests that the constructor worked as expected
// this also tests that the constructor worked as expected
Assertions.assertEquals(mockResultSet, resultSetSourceInfo.getResultSet());
//use the setter to replace the resultset
// use the setter to replace the resultset
ResultSet mockResultSet1 = Mockito.mock(ResultSet.class);
resultSetSourceInfo.setResultSet(mockResultSet1);
Assertions.assertEquals(mockResultSet1, resultSetSourceInfo.getResultSet());
@ -47,5 +47,4 @@ class ResultSetSourceInfoTest {
Assertions.assertTrue(resultSetSourceInfo.toString().contains(uuid.toString()));
}
}
}

Просмотреть файл

@ -25,4 +25,4 @@ class SourceInfoTest {
void StreamSourceInfoConstructor_StreamIsNull_NullPointerException() {
assertThrows(NullPointerException.class, () -> new StreamSourceInfo(null));
}
}
}

390
kusto-style.xml Normal file
Просмотреть файл

@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="KustoStyle" version="21">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter\\:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter\\:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="32"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

Просмотреть файл

@ -106,6 +106,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.16.0</version>
<configuration>
<configFile>${session.executionRootDirectory}/kusto-style.xml</configFile>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

390
quickstart/kusto-style.xml Normal file
Просмотреть файл

@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="KustoStyle" version="21">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter\\:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter\\:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="32"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

Просмотреть файл

@ -92,6 +92,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.16.0</version>
<configuration>
<configFile>${project.basedir}/kusto-style.xml</configFile>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>

Просмотреть файл

@ -40,16 +40,16 @@ import java.util.concurrent.TimeUnit;
public class KustoSampleApp {
// TODO (config - optional): Change the authentication method from "User Prompt" to any of the other options
// Some of the auth modes require additional environment variables to be set in order to work (see usage in generateConnectionString below)
// Managed Identity Authentication only works when running as an Azure service (webapp, function, etc.)
// Some of the auth modes require additional environment variables to be set in order to work (see usage in generateConnectionString below)
// Managed Identity Authentication only works when running as an Azure service (webapp, function, etc.)
private static final String AUTHENTICATION_MODE = "UserPrompt"; // Options: (UserPrompt|ManagedIdentity|AppKey|AppCertificate|DeviceCode)
// TODO (config - optional): Toggle to false to execute this script "unattended"
private static final boolean WAIT_FOR_USER = true;
// TODO (config):
// If this quickstart app was downloaded from OneClick, kusto_sample_config.json should be pre-populated with your cluster's details
// If this quickstart app was downloaded from GitHub, edit kusto_sample_config.json and modify the cluster URL and database fields appropriately
// If this quickstart app was downloaded from OneClick, kusto_sample_config.json should be pre-populated with your cluster's details
// If this quickstart app was downloaded from GitHub, edit kusto_sample_config.json and modify the cluster URL and database fields appropriately
private static final String CONFIG_FILE_NAME = "kusto_sample_config.json";
private static final String BATCHING_POLICY = "{ \"MaximumBatchingTimeSpan\": \"00:00:10\", \"MaximumNumberOfItems\": 500, \"MaximumRawDataSizeMB\": 1024 }";
@ -84,7 +84,8 @@ public class KustoSampleApp {
if (useExistingTable) {
if (shouldAlterTable) {
// Tip: Usually table was originally created with a schema appropriate for the data being ingested, so this wouldn't be needed.
// Learn More: For more information about altering table schemas, see: https://docs.microsoft.com/azure/data-explorer/kusto/management/alter-table-command
// Learn More: For more information about altering table schemas, see:
// https://docs.microsoft.com/azure/data-explorer/kusto/management/alter-table-command
alterMergeExistingTableToProvidedSchema(kustoClient, databaseName, tableName, tableSchema);
}
@ -104,19 +105,28 @@ public class KustoSampleApp {
String mappingName = file.get("mappingName");
// Tip: This is generally a one-time configuration.
// Learn More: For more information about providing inline mappings and mapping references, see: https://docs.microsoft.com/azure/data-explorer/kusto/management/mappings
if (!createIngestionMappings(Boolean.parseBoolean(String.valueOf(file.get("useExistingMapping"))), kustoClient, databaseName, tableName, mappingName, file.get("mappingValue"), dataFormat)) {
// Learn More: For more information about providing inline mappings and mapping references, see:
// https://docs.microsoft.com/azure/data-explorer/kusto/management/mappings
if (!createIngestionMappings(
Boolean.parseBoolean(String.valueOf(file.get("useExistingMapping"))),
kustoClient,
databaseName,
tableName,
mappingName,
file.get("mappingValue"),
dataFormat)) {
continue;
}
// Learn More: For more information about ingesting data to Kusto in Java, see: https://docs.microsoft.com/azure/data-explorer/java-ingest-data
// Learn More: For more information about ingesting data to Kusto in Java, see:
// https://docs.microsoft.com/azure/data-explorer/java-ingest-data
ingest(file, dataFormat, ingestClient, databaseName, tableName, mappingName, ignoreFirstRecord);
}
/*
* Note: We poll here the ingestion's target table because monitoring successful ingestions is expensive and not recommended.
* Instead, the recommended ingestion monitoring approach is to monitor failures.
* Learn more: https://docs.microsoft.com/azure/data-explorer/kusto/api/netfx/kusto-ingest-client-status#tracking-ingestion-status-kustoqueuedingestclient
* and https://docs.microsoft.com/azure/data-explorer/using-diagnostic-logs
* Note: We poll here the ingestion's target table because monitoring successful ingestions is expensive and not recommended. Instead, the
* recommended ingestion monitoring approach is to monitor failures. Learn more:
* https://docs.microsoft.com/azure/data-explorer/kusto/api/netfx/kusto-ingest-client-status#tracking-ingestion-status-kustoqueuedingestclient
* and https://docs.microsoft.com/azure/data-explorer/using-diagnostic-logs
*/
waitForIngestionToComplete();
}
@ -180,7 +190,8 @@ public class KustoSampleApp {
}
private static ConnectionStringBuilder generateConnectionString(String clusterUrl, String authenticationMode) {
// Learn More: For additional information on how to authorize users and apps in Kusto, see: https://docs.microsoft.com/azure/data-explorer/manage-database-permissions
// Learn More: For additional information on how to authorize users and apps in Kusto, see:
// https://docs.microsoft.com/azure/data-explorer/manage-database-permissions
ConnectionStringBuilder csb = null;
switch (authenticationMode) {
case "UserPrompt":
@ -191,9 +202,11 @@ public class KustoSampleApp {
csb = createManagedIdentityConnectionString(clusterUrl);
break;
case "AppKey":
// Learn More: For information about how to procure an AAD Application, see: https://docs.microsoft.com/azure/data-explorer/provision-azure-ad-app
// Learn More: For information about how to procure an AAD Application, see:
// https://docs.microsoft.com/azure/data-explorer/provision-azure-ad-app
// TODO (config - optional): App ID & tenant, and App Key to authenticate with
csb = ConnectionStringBuilder.createWithAadApplicationCredentials(clusterUrl,
csb = ConnectionStringBuilder.createWithAadApplicationCredentials(
clusterUrl,
System.getenv("APP_ID"),
System.getenv("APP_KEY"),
System.getenv("APP_TENANT"));
@ -249,12 +262,10 @@ public class KustoSampleApp {
}
/*
Learn More:
Kusto batches data for ingestion efficiency. The default batching policy ingests data when one of the following conditions are met:
1) More than 1,000 files were queued for ingestion for the same table by the same user
2) More than 1GB of data was queued for ingestion for the same table by the same user
3) More than 5 minutes have passed since the first file was queued for ingestion for the same table by the same user
For more information about customizing the ingestion batching policy, see: https://docs.microsoft.com/azure/data-explorer/kusto/management/batchingpolicy
* Learn More: Kusto batches data for ingestion efficiency. The default batching policy ingests data when one of the following conditions are met: 1)
* More than 1,000 files were queued for ingestion for the same table by the same user 2) More than 1GB of data was queued for ingestion for the same
* table by the same user 3) More than 5 minutes have passed since the first file was queued for ingestion for the same table by the same user For more
* information about customizing the ingestion batching policy, see: https://docs.microsoft.com/azure/data-explorer/kusto/management/batchingpolicy
*/
// Disabled to prevent an existing batching policy from being unintentionally changed
if (false) {
@ -275,7 +286,8 @@ public class KustoSampleApp {
KustoOperationResult result;
try {
result = kustoClient.execute(databaseName, controlCommand, clientRequestProperties);
// Tip: Actual implementations wouldn't generally print the response from a control command. We print here to demonstrate what the response looks like.
// Tip: Actual implementations wouldn't generally print the response from a control command. We print here to demonstrate what the response looks
// like.
System.out.printf("Response from executed control command '%s':%n", controlCommand);
KustoResultSetTable primaryResults = result.getPrimaryResults();
for (int rowNum = 1; primaryResults.next(); rowNum++) {
@ -284,7 +296,11 @@ public class KustoSampleApp {
System.out.printf("Record %s%n", rowNum);
for (int j = 0; j < currentRow.size(); j++) {
Object cell = currentRow.get(j);
System.out.printf("Column: '%s' of type '%s', Value: '%s'%n", columns[j].getColumnName(), columns[j].getColumnType(), cell == null ? "[null]" : cell);
System.out.printf(
"Column: '%s' of type '%s', Value: '%s'%n",
columns[j].getColumnName(),
columns[j].getColumnType(),
cell == null ? "[null]" : cell);
}
System.out.println();
}
@ -315,7 +331,11 @@ public class KustoSampleApp {
System.out.printf("Record %s%n", rowNum);
for (int j = 0; j < currentRow.size(); j++) {
Object cell = currentRow.get(j);
System.out.printf("Column: '%s' of type '%s', Value: '%s'%n", columns[j].getColumnName(), columns[j].getColumnType(), cell == null ? "[null]" : cell);
System.out.printf(
"Column: '%s' of type '%s', Value: '%s'%n",
columns[j].getColumnName(),
columns[j].getColumnType(),
cell == null ? "[null]" : cell);
}
System.out.println();
}
@ -355,19 +375,26 @@ public class KustoSampleApp {
private static void alterBatchingPolicy(Client kustoClient, String databaseName, String tableName) {
/*
Tip 1: Though most users should be fine with the defaults, to speed up ingestion, such as during development and
in this sample app, we opt to modify 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.
* Tip 1: Though most users should be fine with the defaults, to speed up ingestion, such as during development and in this sample app, we opt to modify
* 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.
*/
waitForUserToProceed(String.format("Alter the batching policy for table '%s.%s'", databaseName, tableName));
String command = String.format(".alter table %s policy ingestionbatching @'%s'", tableName, BATCHING_POLICY);
if (!executeControlCommand(kustoClient, databaseName, command)) {
System.out.println("Failed to alter the ingestion policy, which could be the result of insufficient permissions. The sample will still run, though ingestion will be delayed for up to 5 minutes.");
System.out.println(
"Failed to alter the ingestion policy, which could be the result of insufficient permissions. The sample will still run, though ingestion will be delayed for up to 5 minutes.");
}
}
private static boolean createIngestionMappings(boolean useExistingMapping, Client kustoClient, String databaseName, String tableName, String mappingName, String mappingValue, IngestionProperties.DataFormat dataFormat) {
private static boolean createIngestionMappings(
boolean useExistingMapping,
Client kustoClient,
String databaseName,
String tableName,
String mappingName,
String mappingValue,
IngestionProperties.DataFormat dataFormat) {
if (!useExistingMapping && StringUtils.isNotBlank(mappingValue)) {
IngestionMapping.IngestionMappingKind ingestionMappingKind = dataFormat.getIngestionMappingKind();
waitForUserToProceed(String.format("Create a '%s' mapping reference named '%s'", ingestionMappingKind.getKustoValue(), mappingName));
@ -375,27 +402,42 @@ public class KustoSampleApp {
if (StringUtils.isBlank(mappingName)) {
mappingName = "DefaultQuickstartMapping" + UUID.randomUUID().toString().substring(0, 5);
}
String mappingCommand = String.format(".create-or-alter table %s ingestion %s mapping '%s' '%s'", tableName, ingestionMappingKind.getKustoValue().toLowerCase(), mappingName, mappingValue);
String mappingCommand = String.format(
".create-or-alter table %s ingestion %s mapping '%s' '%s'",
tableName,
ingestionMappingKind.getKustoValue().toLowerCase(),
mappingName,
mappingValue);
if (!executeControlCommand(kustoClient, databaseName, mappingCommand)) {
System.out.printf("Failed to create a '%s' mapping reference named '%s'. Skipping this ingestion.%n", ingestionMappingKind.getKustoValue(), mappingName);
System.out.printf(
"Failed to create a '%s' mapping reference named '%s'. Skipping this ingestion.%n",
ingestionMappingKind.getKustoValue(),
mappingName);
return false;
}
}
return true;
}
private static void ingest(Map<String, String> file, IngestionProperties.DataFormat dataFormat, IngestClient ingestClient, String databaseName, String tableName, String mappingName, boolean ignoreFirstRecord) {
private static void ingest(
Map<String, String> file,
IngestionProperties.DataFormat dataFormat,
IngestClient ingestClient,
String databaseName,
String tableName,
String mappingName,
boolean ignoreFirstRecord) {
String sourceType = file.get("sourceType");
String uri = file.get("dataSourceUri");
waitForUserToProceed(String.format("Ingest '%s' from '%s'", uri, sourceType));
// Tip: When ingesting json files, if each line represents a single-line json, use MULTIJSON format even if the file only contains one line.
// If the json contains whitespace formatting, use SINGLEJSON. In this case, only one data row json object is allowed per file.
// If the json contains whitespace formatting, use SINGLEJSON. In this case, only one data row json object is allowed per file.
if (dataFormat == IngestionProperties.DataFormat.JSON) {
dataFormat = IngestionProperties.DataFormat.MULTIJSON;
}
// Tip: Kusto's Java SDK can ingest data from files, blobs, java.sql.ResultSet objects, and open streams.
// See the SDK's kusto-samples module and the E2E tests in kusto-ingest for additional references.
// See the SDK's kusto-samples module and the E2E tests in kusto-ingest for additional references.
if (sourceType.equalsIgnoreCase("localfilesource")) {
ingestFromFile(ingestClient, databaseName, tableName, uri, dataFormat, mappingName, ignoreFirstRecord);
} else if (sourceType.equalsIgnoreCase("blobsource")) {
@ -405,11 +447,19 @@ public class KustoSampleApp {
}
}
private static void ingestFromFile(IngestClient ingestClient, String databaseName, String tableName, String filePath, IngestionProperties.DataFormat dataFormat, String mappingName, boolean ignoreFirstRecord) {
private static void ingestFromFile(
IngestClient ingestClient,
String databaseName,
String tableName,
String filePath,
IngestionProperties.DataFormat dataFormat,
String mappingName,
boolean ignoreFirstRecord) {
IngestionProperties ingestionProperties = createIngestionProperties(databaseName, tableName, dataFormat, mappingName, ignoreFirstRecord);
// Tip 1: For optimal ingestion batching and performance, specify the uncompressed data size in the file descriptor (e.g. fileToIngest.length()) instead of the default below of 0.
// Otherwise, the service will determine the file size, requiring an additional s2s call and may not be accurate for compressed files.
// Tip 1: For optimal ingestion batching and performance, specify the uncompressed data size in the file descriptor (e.g. fileToIngest.length()) instead
// of the default below of 0.
// Otherwise, the service will determine the file size, requiring an additional s2s call and may not be accurate for compressed files.
// Tip 2: To correlate between ingestion operations in your applications and Kusto, set the source ID and log it somewhere.
FileSourceInfo fileSourceInfo = new FileSourceInfo(filePath, 0, UUID.randomUUID());
try {
@ -423,11 +473,18 @@ public class KustoSampleApp {
}
}
private static void ingestFromBlob(IngestClient ingestClient, String databaseName, String tableName, String blobUrl, IngestionProperties.DataFormat dataFormat, String mappingName, boolean ignoreFirstRecord) {
private static void ingestFromBlob(
IngestClient ingestClient,
String databaseName,
String tableName,
String blobUrl,
IngestionProperties.DataFormat dataFormat,
String mappingName,
boolean ignoreFirstRecord) {
IngestionProperties ingestionProperties = createIngestionProperties(databaseName, tableName, dataFormat, mappingName, ignoreFirstRecord);
// Tip 1: For optimal ingestion batching and performance, specify the uncompressed data size in the file descriptor instead of the default below of 0.
// Otherwise, the service will determine the file size, requiring an additional s2s call and may not be accurate for compressed files.
// Otherwise, the service will determine the file size, requiring an additional s2s call and may not be accurate for compressed files.
// Tip 2: To correlate between ingestion operations in your applications and Kusto, set the source ID and log it somewhere.
BlobSourceInfo blobSourceInfo = new BlobSourceInfo(blobUrl, 0, UUID.randomUUID());
try {
@ -442,7 +499,12 @@ public class KustoSampleApp {
}
@NotNull
private static IngestionProperties createIngestionProperties(String databaseName, String tableName, IngestionProperties.DataFormat dataFormat, String mappingName, boolean ignoreFirstRecord) {
private static IngestionProperties createIngestionProperties(
String databaseName,
String tableName,
IngestionProperties.DataFormat dataFormat,
String mappingName,
boolean ignoreFirstRecord) {
IngestionProperties ingestionProperties = new IngestionProperties(databaseName, tableName);
ingestionProperties.setDataFormat(dataFormat);
// Learn More: For more information about supported data formats, see: https://docs.microsoft.com/azure/data-explorer/ingestion-supported-formats
@ -451,14 +513,16 @@ public class KustoSampleApp {
}
ingestionProperties.setIgnoreFirstRecord(ignoreFirstRecord);
// TODO (config - optional): Setting the ingestion batching policy takes up to 5 minutes to take effect.
// We therefore set Flush-Immediately for the sake of the sample, but it generally shouldn't be used in practice.
// Comment out the line below after running the sample the first few times.
// We therefore set Flush-Immediately for the sake of the sample, but it generally shouldn't be used in practice.
// Comment out the line below after running the sample the first few times.
ingestionProperties.setFlushImmediately(true);
return ingestionProperties;
}
private static void waitForIngestionToComplete() throws InterruptedException {
System.out.printf("Sleeping %s seconds for queued ingestion to complete. Note: This may take longer depending on the file size and ingestion batching policy.%n", WAIT_FOR_INGEST_SECONDS);
System.out.printf(
"Sleeping %s seconds for queued ingestion to complete. Note: This may take longer depending on the file size and ingestion batching policy.%n",
WAIT_FOR_INGEST_SECONDS);
for (int i = WAIT_FOR_INGEST_SECONDS; i >= 0; i--) {
System.out.printf("%s.", i);
try {
@ -483,4 +547,4 @@ public class KustoSampleApp {
executeQuery(kustoClient, databaseName, String.format("%s | take 2", tableName));
System.out.println();
}
}
}

Просмотреть файл

@ -45,4 +45,4 @@
</dependency>
</dependencies>
</project>
</project>

Просмотреть файл

@ -17,13 +17,14 @@ import java.io.ByteArrayOutputStream;
public class FileIngestion {
public static void main(String[] args) {
try {
ConnectionStringBuilder csb =
ConnectionStringBuilder.createWithAadApplicationCredentials(System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadApplicationCredentials(
System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
try (IngestClient client = IngestClientFactory.createClient(csb)) {
IngestionProperties ingestionProperties = new IngestionProperties(System.getProperty("dbName"),
IngestionProperties ingestionProperties = new IngestionProperties(
System.getProperty("dbName"),
System.getProperty("tableName"));
ingestionProperties.setIngestionMapping(System.getProperty("dataMappingName"), IngestionMapping.IngestionMappingKind.JSON);
@ -35,14 +36,15 @@ public class FileIngestion {
StreamSourceInfo info = new StreamSourceInfo(byteArrayInputStream);
// Ingest with inline ingestion mapping - less recommended
IngestionProperties ingestionProperties2 = new IngestionProperties(System.getProperty("dbName"),
IngestionProperties ingestionProperties2 = new IngestionProperties(
System.getProperty("dbName"),
System.getProperty("tableName"));
ColumnMapping csvColumnMapping = new ColumnMapping("ColA", "string");
csvColumnMapping.setOrdinal(0);
ColumnMapping csvColumnMapping2 = new ColumnMapping("ColB", "int");
csvColumnMapping2.setOrdinal(1);
ingestionProperties2.setDataFormat(IngestionProperties.DataFormat.CSV);
ingestionProperties2.setIngestionMapping(new ColumnMapping[]{csvColumnMapping, csvColumnMapping2}, IngestionMapping.IngestionMappingKind.CSV);
ingestionProperties2.setIngestionMapping(new ColumnMapping[] {csvColumnMapping, csvColumnMapping2}, IngestionMapping.IngestionMappingKind.CSV);
IngestionResult ingestionResult2 = client.ingestFromStream(info, ingestionProperties2);
}
@ -50,4 +52,4 @@ public class FileIngestion {
e.printStackTrace();
}
}
}
}

Просмотреть файл

@ -21,12 +21,11 @@ public class FileIngestionCompletableFuture {
public static void main(String[] args) {
try {
// Creating the connection string:
ConnectionStringBuilder csb =
ConnectionStringBuilder.createWithAadApplicationCredentials(
System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadApplicationCredentials(
System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
CompletableFuture<IngestionResult> cf;
try (IngestClient client = IngestClientFactory.createClient(csb)) {
@ -75,7 +74,9 @@ public class FileIngestionCompletableFuture {
* @return a {@link CompletableFuture}
*/
private static CompletableFuture<IngestionResult> ingestFromFileAsync(
IngestClient client, FileSourceInfo fileSourceInfo, IngestionProperties ingestionProperties) {
IngestClient client,
FileSourceInfo fileSourceInfo,
IngestionProperties ingestionProperties) {
return CompletableFuture.supplyAsync(
() -> {
try {
@ -97,4 +98,4 @@ public class FileIngestionCompletableFuture {
}
}
}
}

Просмотреть файл

@ -67,8 +67,9 @@ public class StreamingIngest {
// Open compressed CSV File Stream and Ingest
FileInputStream fileInputStream = new FileInputStream(resourcesDirectory + "dataset.csv.gz");
streamSourceInfo.setStream(fileInputStream);
/* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed.
* When the given stream content is already compressed, we should set this property true to avoid double compression.
/*
* In order to make efficient ingestion requests, the streaming ingest client compress the given stream unless it is already compressed. When the given
* stream content is already compressed, we should set this property true to avoid double compression.
*/
streamSourceInfo.setCompressionType(CompressionType.gz);
status = streamingIngestClient.ingestFromStream(streamSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
@ -86,14 +87,14 @@ public class StreamingIngest {
static void ingestFromFile() throws IngestionClientException, IngestionServiceException, URISyntaxException, StorageException {
IngestionProperties ingestionProperties = new IngestionProperties(database, table);
String resourcesDirectory = System.getProperty("user.dir") + "/samples/src/main/resources/";
//Ingest CSV file
// Ingest CSV file
String path = resourcesDirectory + "dataset.csv";
FileSourceInfo fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.CSV);
OperationStatus status = streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
System.out.println(status.toString());
//Ingest compressed JSON file
// Ingest compressed JSON file
path = resourcesDirectory + "dataset.jsonz.gz";
fileSourceInfo = new FileSourceInfo(path, new File(path).length());
ingestionProperties.setDataFormat(IngestionProperties.DataFormat.JSON);
@ -101,4 +102,4 @@ public class StreamingIngest {
status = streamingIngestClient.ingestFromFile(fileSourceInfo, ingestionProperties).getIngestionStatusCollection().get(0).status;
System.out.println(status.toString());
}
}
}

Просмотреть файл

@ -21,14 +21,15 @@ public class TableStatus {
try {
Integer timeoutInSec = Integer.getInteger("timeoutInSec");
ConnectionStringBuilder csb =
ConnectionStringBuilder.createWithAadApplicationCredentials(System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadApplicationCredentials(
System.getProperty("clusterPath"),
System.getProperty("appId"),
System.getProperty("appKey"),
System.getProperty("appTenant"));
IngestionResult ingestionResult;
try (IngestClient client = IngestClientFactory.createClient(csb)) {
IngestionProperties ingestionProperties = new IngestionProperties(System.getProperty("dbName"),
IngestionProperties ingestionProperties = new IngestionProperties(
System.getProperty("dbName"),
System.getProperty("tableName"));
ingestionProperties.setIngestionMapping(System.getProperty("dataMappingName"), IngestionMapping.IngestionMappingKind.JSON);
ingestionProperties.setReportMethod(QUEUE_AND_TABLE);
@ -52,4 +53,4 @@ public class TableStatus {
e.printStackTrace();
}
}
}
}