Skip to content

Commit 301a92d

Browse files
authored
Support getting rows as objects and map errors (Azure#21997)
* Update samples and map errors * Fix version tag
1 parent d39fda7 commit 301a92d

File tree

8 files changed

+524
-18
lines changed

8 files changed

+524
-18
lines changed

sdk/monitor/azure-monitor-query/README.md

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,127 @@ LogsAsyncClient logsAsyncClient = new LogsClientBuilder()
9090
+ "; value = " + logsTableCell.getValueAsString()));
9191
}
9292
}
93-
}
93+
94+
```
95+
### Get logs for a query and read the response as a model type
96+
97+
```java
98+
99+
LogsQueryResult queryResults = logsClient
100+
.queryLogs("d2d0e126-fa1e-4b0a-b647-250cdd471e68", "AppRequests", null);
101+
102+
// Sample to use a model type to read the results
103+
for (LogsTable table : queryResults.getLogsTables()) {
104+
for (LogsTableRow row : table.getTableRows()) {
105+
CustomModel model = row.getRowAsObject(CustomModel.class);
106+
System.out.println("Time generated " + model.getTimeGenerated() + "; success = " + model.getSuccess() +
107+
"; operation name = " + model.getOperationName());
108+
}
109+
}
110+
111+
112+
public class CustomModel {
113+
private OffsetDateTime timeGenerated;
114+
private String tenantId;
115+
private String id;
116+
private String source;
117+
private Boolean success;
118+
private Double durationMs;
119+
private Object properties;
120+
private Object measurements;
121+
private String operationName;
122+
private String operationId;
123+
private Object operationLinks;
124+
125+
126+
public OffsetDateTime getTimeGenerated() {
127+
return timeGenerated;
128+
}
129+
130+
public void setTimeGenerated(OffsetDateTime timeGenerated) {
131+
this.timeGenerated = timeGenerated;
132+
}
133+
134+
public String getTenantId() {
135+
return tenantId;
136+
}
137+
138+
public void setTenantId(String tenantId) {
139+
this.tenantId = tenantId;
140+
}
141+
142+
public String getId() {
143+
return id;
144+
}
145+
146+
public void setId(String id) {
147+
this.id = id;
148+
}
149+
150+
public String getSource() {
151+
return source;
152+
}
153+
154+
public void setSource(String source) {
155+
this.source = source;
156+
}
157+
158+
public Boolean getSuccess() {
159+
return success;
160+
}
161+
162+
public void setSuccess(Boolean success) {
163+
this.success = success;
164+
}
165+
166+
public Double getDurationMs() {
167+
return durationMs;
168+
}
169+
170+
public void setDurationMs(Double durationMs) {
171+
this.durationMs = durationMs;
172+
}
173+
174+
public Object getProperties() {
175+
return properties;
176+
}
177+
178+
public void setProperties(Object properties) {
179+
this.properties = properties;
180+
}
181+
182+
public Object getMeasurements() {
183+
return measurements;
184+
}
185+
186+
public void setMeasurements(Object measurements) {
187+
this.measurements = measurements;
188+
}
189+
190+
public String getOperationName() {
191+
return operationName;
192+
}
193+
194+
public void setOperationName(String operationName) {
195+
this.operationName = operationName;
196+
}
197+
198+
public String getOperationId() {
199+
return operationId;
200+
}
201+
202+
public void setOperationId(String operationId) {
203+
this.operationId = operationId;
204+
}
205+
206+
public Object getOperationLinks() {
207+
return operationLinks;
208+
}
209+
210+
public void setOperationLinks(Object operationLinks) {
211+
this.operationLinks = operationLinks;
212+
}
213+
}
94214
```
95215

96216
### Get logs for a batch of queries
@@ -272,7 +392,7 @@ client library to use the Netty HTTP client. Configuring or changing the HTTP cl
272392

273393
All client libraries, by default, use the Tomcat-native Boring SSL library to enable native-level performance for SSL
274394
operations. The Boring SSL library is an uber jar containing native libraries for Linux / macOS / Windows, and provides
275-
better performance compared to the default SSL implementation within the JDK. For more information, including how to
395+
better performance compared to the default SSL com.azure.monitor.collect.metrics.implementation within the JDK. For more information, including how to
276396
reduce the dependency size, refer to the [performance tuning][performance_tuning] section of the wiki.
277397

278398
## Next steps

sdk/monitor/azure-monitor-query/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@
7373
<version>1.6.2</version> <!-- {x-version-update;com.azure:azure-core-test;dependency} -->
7474
<scope>test</scope>
7575
</dependency>
76+
<dependency>
77+
<groupId>com.azure</groupId>
78+
<artifactId>azure-core-serializer-json-jackson</artifactId>
79+
<version>1.2.3</version> <!-- {x-version-update;com.azure:azure-core-serializer-json-jackson;dependency} -->
80+
<scope>test</scope>
81+
</dependency>
7682
</dependencies>
7783

7884
<build>

sdk/monitor/azure-monitor-query/src/main/java/com/azure/monitor/query/LogsAsyncClient.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.azure.monitor.query.log.implementation.models.BatchRequest;
1414
import com.azure.monitor.query.log.implementation.models.BatchResponse;
1515
import com.azure.monitor.query.log.implementation.models.ErrorInfo;
16+
import com.azure.monitor.query.log.implementation.models.ErrorResponseException;
1617
import com.azure.monitor.query.log.implementation.models.LogQueryRequest;
1718
import com.azure.monitor.query.log.implementation.models.LogQueryResponse;
1819
import com.azure.monitor.query.log.implementation.models.LogQueryResult;
@@ -22,7 +23,9 @@
2223
import com.azure.monitor.query.models.LogsQueryBatch;
2324
import com.azure.monitor.query.models.LogsQueryBatchResult;
2425
import com.azure.monitor.query.models.LogsQueryBatchResultCollection;
26+
import com.azure.monitor.query.models.LogsQueryError;
2527
import com.azure.monitor.query.models.LogsQueryErrorDetails;
28+
import com.azure.monitor.query.models.LogsQueryException;
2629
import com.azure.monitor.query.models.LogsQueryOptions;
2730
import com.azure.monitor.query.models.LogsQueryResult;
2831
import com.azure.monitor.query.models.LogsTable;
@@ -33,6 +36,7 @@
3336
import reactor.core.publisher.Mono;
3437

3538
import java.util.ArrayList;
39+
import java.util.Collections;
3640
import java.util.Comparator;
3741
import java.util.List;
3842
import java.util.concurrent.atomic.AtomicInteger;
@@ -128,6 +132,14 @@ Mono<Response<LogsQueryBatchResultCollection>> queryLogsBatchWithResponse(LogsQu
128132
batchRequest.setRequests(requests);
129133

130134
return innerClient.getQueries().batchWithResponseAsync(batchRequest, context)
135+
.onErrorMap(ex -> {
136+
if (ex instanceof ErrorResponseException) {
137+
ErrorResponseException error = (ErrorResponseException) ex;
138+
ErrorInfo errorInfo = error.getValue().getError();
139+
return new LogsQueryException(error.getResponse(), mapLogsQueryError(errorInfo));
140+
}
141+
return ex;
142+
})
131143
.map(this::convertToLogQueryBatchResult);
132144
}
133145

@@ -139,17 +151,39 @@ private Response<LogsQueryBatchResultCollection> convertToLogQueryBatchResult(Re
139151
for (LogQueryResponse singleQueryResponse : batchResponse.getResponses()) {
140152
LogsQueryBatchResult logsQueryBatchResult = new LogsQueryBatchResult(singleQueryResponse.getId(),
141153
singleQueryResponse.getStatus(), getLogsQueryResult(singleQueryResponse.getBody()),
142-
mapLogsQueryBatchError(singleQueryResponse.getBody().getError()));
154+
mapLogsQueryError(singleQueryResponse.getBody().getError()));
143155
batchResults.add(logsQueryBatchResult);
144156
}
145157
batchResults.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getId())));
146158
return new SimpleResponse<>(response.getRequest(), response.getStatusCode(), response.getHeaders(), logsQueryBatchResultCollection);
147159
}
148160

149-
private LogsQueryErrorDetails mapLogsQueryBatchError(ErrorInfo errors) {
161+
private LogsQueryErrorDetails mapLogsQueryError(ErrorInfo errors) {
150162
if (errors != null) {
151-
return new LogsQueryErrorDetails(errors.getMessage(), errors.getCode(),
152-
errors.getDetails().get(0).getTarget());
163+
List<LogsQueryError> errorDetails = Collections.emptyList();
164+
if (errors.getDetails() != null) {
165+
errorDetails = errors.getDetails()
166+
.stream()
167+
.map(errorDetail -> new LogsQueryError(errorDetail.getCode(),
168+
errorDetail.getMessage(),
169+
errorDetail.getTarget(),
170+
errorDetail.getValue(),
171+
errorDetail.getResources(),
172+
errorDetail.getAdditionalProperties()))
173+
.collect(Collectors.toList());
174+
}
175+
176+
ErrorInfo innerError = errors.getInnererror();
177+
ErrorInfo currentError = errors.getInnererror();
178+
while (currentError != null) {
179+
innerError = errors.getInnererror();
180+
currentError = errors.getInnererror();
181+
}
182+
String code = errors.getCode();
183+
if (!errors.getCode().equals(innerError.getCode())) {
184+
code = innerError.getCode();
185+
}
186+
return new LogsQueryErrorDetails(errors.getMessage(), code, errorDetails);
153187
}
154188
return null;
155189
}
@@ -186,6 +220,14 @@ Mono<Response<LogsQueryResult>> queryLogsWithResponse(LogsQueryOptions options,
186220
queryBody,
187221
preferHeader,
188222
context)
223+
.onErrorMap(ex -> {
224+
if (ex instanceof ErrorResponseException) {
225+
ErrorResponseException error = (ErrorResponseException) ex;
226+
ErrorInfo errorInfo = error.getValue().getError();
227+
return new LogsQueryException(error.getResponse(), mapLogsQueryError(errorInfo));
228+
}
229+
return ex;
230+
})
189231
.map(this::convertToLogQueryResult);
190232
}
191233

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.monitor.query.models;
5+
6+
import java.util.List;
7+
8+
/**
9+
* Error details of a failed log query.
10+
*/
11+
12+
public final class LogsQueryError {
13+
/*
14+
* The error's code.
15+
*/
16+
private final String code;
17+
18+
/*
19+
* A human readable error message.
20+
*/
21+
private final String message;
22+
23+
/*
24+
* Indicates which property in the request is responsible for the error.
25+
*/
26+
private final String target;
27+
28+
/*
29+
* Indicates which value in 'target' is responsible for the error.
30+
*/
31+
private final String value;
32+
33+
/*
34+
* Indicates resources which were responsible for the error.
35+
*/
36+
private final List<String> resources;
37+
38+
/*
39+
* Additional properties that can be provided on the error details object
40+
*/
41+
private final Object additionalProperties;
42+
43+
/**
44+
* Creates an instance of ErrorDetail class.
45+
* @param code the code value to set.
46+
* @param message the message value to set.
47+
* @param target indicates which property in the request is responsible for the error.
48+
* @param value indicates which value in 'target' is responsible for the error.
49+
* @param resources indicates resources which were responsible for the error.
50+
* @param additionalProperties additional properties that can be provided on the error details object
51+
*/
52+
public LogsQueryError(
53+
String code,
54+
String message,
55+
String target,
56+
String value,
57+
List<String> resources,
58+
Object additionalProperties) {
59+
this.code = code;
60+
this.message = message;
61+
this.target = target;
62+
this.value = value;
63+
this.resources = resources;
64+
this.additionalProperties = additionalProperties;
65+
}
66+
67+
/**
68+
* Get the code property: The error's code.
69+
* @return the code value.
70+
*/
71+
public String getCode() {
72+
return this.code;
73+
}
74+
75+
/**
76+
* Get the message property: A human readable error message.
77+
* @return the message value.
78+
*/
79+
public String getMessage() {
80+
return this.message;
81+
}
82+
83+
/**
84+
* Get the target property: Indicates which property in the request is responsible for the error.
85+
* @return the target value.
86+
*/
87+
public String getTarget() {
88+
return this.target;
89+
}
90+
91+
/**
92+
* Get the value property: Indicates which value in 'target' is responsible for the error.
93+
* @return the value value.
94+
*/
95+
public String getValue() {
96+
return this.value;
97+
}
98+
99+
/**
100+
* Get the resources property: Indicates resources which were responsible for the error.
101+
* @return the resources value.
102+
*/
103+
public List<String> getResources() {
104+
return this.resources;
105+
}
106+
107+
/**
108+
* Get the additionalProperties property: Additional properties that can be provided on the error details object.
109+
* @return the additionalProperties value.
110+
*/
111+
public Object getAdditionalProperties() {
112+
return this.additionalProperties;
113+
}
114+
}

0 commit comments

Comments
 (0)