Skip to content

Commit 705cf60

Browse files
Merge pull request #27 from epam/longNumberFormat-1.2
Long number format 1.2
2 parents cfae01d + abc26e7 commit 705cf60

25 files changed

+356
-63
lines changed

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/config/WebMvcConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,19 @@
1818

1919
import com.epam.deltix.tbwg.webapp.interceptors.TimebaseLoginInterceptor;
2020
import com.epam.deltix.tbwg.webapp.interceptors.RestLogInterceptor;
21+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncodingArgumentResolver;
2122
import org.springframework.beans.factory.annotation.Autowired;
2223
import org.springframework.context.annotation.Configuration;
2324
import org.springframework.core.task.AsyncTaskExecutor;
25+
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
2426
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
2527
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
2628
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
2729
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
2830
import org.springframework.web.util.UrlPathHelper;
2931

32+
import java.util.List;
33+
3034
@Configuration
3135
public class WebMvcConfig implements WebMvcConfigurer {
3236

@@ -37,6 +41,9 @@ public class WebMvcConfig implements WebMvcConfigurer {
3741
private final RestLogInterceptor logInterceptor;
3842
private final TimebaseLoginInterceptor timebaseLoginInterceptor;
3943

44+
@Autowired
45+
private JsonBigIntEncodingArgumentResolver argumentResolver;
46+
4047
@Autowired
4148
public WebMvcConfig(AsyncTaskExecutor asyncTaskExecutor,
4249
RestLogInterceptor logInterceptor,
@@ -65,4 +72,9 @@ public void addInterceptors(InterceptorRegistry registry) {
6572
registry.addInterceptor(logInterceptor);
6673
registry.addInterceptor(timebaseLoginInterceptor);
6774
}
75+
76+
@Override
77+
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
78+
resolvers.add(argumentResolver);
79+
}
6880
}

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/controllers/MonitorController.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.epam.deltix.tbwg.webapp.config.WebSocketConfig;
2020
import com.epam.deltix.tbwg.webapp.services.timebase.MonitorService;
2121
import com.epam.deltix.tbwg.webapp.utils.HeaderAccessorHelper;
22+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncoding;
2223
import com.epam.deltix.tbwg.webapp.websockets.subscription.Subscription;
2324
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionChannel;
2425
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionController;
@@ -53,8 +54,9 @@ public Subscription onSubscribe(SimpMessageHeaderAccessor headerAccessor, Subscr
5354
long fromTimestamp = headerAccessorHelper.getTimestamp(headerAccessor);
5455
List<String> symbols = headerAccessorHelper.getSymbols(headerAccessor);
5556
List<String> types = headerAccessorHelper.getTypes(headerAccessor);
57+
JsonBigIntEncoding bigIntEncoding = HeaderAccessorHelper.getJsonBigIntEncoding(headerAccessor);
5658

57-
monitorService.subscribe(sessionId, subscriptionId, stream, null, fromTimestamp, types, symbols, channel::sendMessage);
59+
monitorService.subscribe(sessionId, subscriptionId, stream, null, fromTimestamp, types, symbols, channel::sendMessage, bigIntEncoding);
5860
return () -> monitorService.unsubscribe(sessionId, subscriptionId);
5961
}
6062

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/controllers/MonitorQqlController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616
*/
1717
package com.epam.deltix.tbwg.webapp.controllers;
1818

19-
import com.epam.deltix.gflog.api.Log;
20-
import com.epam.deltix.gflog.api.LogFactory;
2119
import com.epam.deltix.tbwg.webapp.config.WebSocketConfig;
2220
import com.epam.deltix.tbwg.webapp.services.timebase.MonitorService;
2321
import com.epam.deltix.tbwg.webapp.utils.HeaderAccessorHelper;
22+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncoding;
2423
import com.epam.deltix.tbwg.webapp.websockets.subscription.Subscription;
2524
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionChannel;
2625
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionController;
@@ -55,8 +54,9 @@ public Subscription onSubscribe(SimpMessageHeaderAccessor headerAccessor, Subscr
5554
long fromTimestamp = headerAccessorHelper.getTimestamp(headerAccessor);
5655
List<String> symbols = headerAccessorHelper.getSymbols(headerAccessor);
5756
List<String> types = headerAccessorHelper.getTypes(headerAccessor);
57+
JsonBigIntEncoding bigIntEncoding = HeaderAccessorHelper.getJsonBigIntEncoding(headerAccessor);
5858

59-
monitorService.subscribe(sessionId, subscriptionId, null, qql, fromTimestamp, types, symbols, channel::sendMessage);
59+
monitorService.subscribe(sessionId, subscriptionId, null, qql, fromTimestamp, types, symbols, channel::sendMessage, bigIntEncoding);
6060
return () -> monitorService.unsubscribe(sessionId, subscriptionId);
6161
}
6262

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/controllers/TimebaseController.java

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.epam.deltix.qsrv.hf.tickdb.pub.lock.LockType;
2626
import com.epam.deltix.qsrv.hf.tickdb.ui.tbshell.TickDBShell;
2727
import com.epam.deltix.tbwg.webapp.model.smd.CurrencyDef;
28+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncoding;
2829
import com.epam.deltix.timebase.messages.IdentityKey;
2930
import com.epam.deltix.timebase.messages.InstrumentKey;
3031
import com.epam.deltix.timebase.messages.InstrumentMessage;
@@ -175,14 +176,14 @@ public long correlationId() {
175176
*/
176177
@PreAuthorize("hasAnyAuthority('TB_ALLOW_READ', 'TB_ALLOW_WRITE')")
177178
@RequestMapping(value = "/select", method = {RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
178-
public ResponseEntity<StreamingResponseBody> select(@Valid @RequestBody(required = false) SelectRequest select)
179-
throws NoStreamsException {
179+
public ResponseEntity<StreamingResponseBody> select(@Valid @RequestBody(required = false) SelectRequest select,
180+
JsonBigIntEncoding bigIntEncoding) throws NoStreamsException {
180181
if (select == null) {
181182
select = new SelectRequest();
182183
}
183184
return ResponseEntity.ok()
184185
.contentType(MediaType.APPLICATION_JSON)
185-
.body(selectService.select(select, MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET));
186+
.body(selectService.select(select, MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET, bigIntEncoding));
186187
}
187188

188189
/**
@@ -217,7 +218,8 @@ public ResponseEntity<StreamingResponseBody> select(
217218
@RequestParam(required = false) Long offset,
218219
@RequestParam(required = false) Integer rows,
219220
@RequestParam(required = false) String space,
220-
@RequestParam(required = false) boolean reverse) throws NoStreamsException {
221+
@RequestParam(required = false) boolean reverse,
222+
JsonBigIntEncoding bigIntEncoding) throws NoStreamsException {
221223
SelectRequest request = new SelectRequest();
222224
request.streams = streams;
223225
request.symbols = symbols;
@@ -230,7 +232,7 @@ public ResponseEntity<StreamingResponseBody> select(
230232
request.reverse = reverse;
231233
request.depth = depth;
232234
request.space = space;
233-
return select(request);
235+
return select(request, bigIntEncoding);
234236
}
235237

236238
/**
@@ -249,13 +251,14 @@ public ResponseEntity<StreamingResponseBody> select(
249251
@PreAuthorize("hasAnyAuthority('TB_ALLOW_READ', 'TB_ALLOW_WRITE')")
250252
@RequestMapping(value = "/{streamId}/select", method = {RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
251253
public ResponseEntity<StreamingResponseBody> select(@PathVariable String streamId,
252-
@Valid @RequestBody(required = false) StreamRequest select)
254+
@Valid @RequestBody(required = false) StreamRequest select,
255+
JsonBigIntEncoding bigIntEncoding)
253256
throws NoStreamsException {
254257
if (select == null)
255258
select = new StreamRequest();
256259

257260
return select(streamId, select.symbols, select.types, null, select.from, select.to, select.offset,
258-
select.rows, select.space, select.reverse);
261+
select.rows, select.space, select.reverse, bigIntEncoding);
259262
}
260263

261264
/**
@@ -297,11 +300,12 @@ public ResponseEntity<StreamingResponseBody> select(
297300
@RequestParam(required = false) Long offset,
298301
@RequestParam(required = false) Integer rows,
299302
@RequestParam(required = false) String space,
300-
@RequestParam(required = false) boolean reverse) throws NoStreamsException {
303+
@RequestParam(required = false) boolean reverse,
304+
JsonBigIntEncoding bigIntEncoding) throws NoStreamsException {
301305
if (TextUtils.isEmpty(streamId))
302306
throw new NoStreamsException();
303307

304-
return select(new String[]{streamId}, symbols, types, depth, from, to, offset, rows, space, reverse);
308+
return select(new String[]{streamId}, symbols, types, depth, from, to, offset, rows, space, reverse, bigIntEncoding);
305309
}
306310

307311
// download operation is permitted for any user
@@ -1025,7 +1029,7 @@ ResponseEntity<StreamingResponseBody> checkWritable(String error) {
10251029
@RequestMapping(value = "/{streamId}/{symbolId}/select", method = {RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
10261030
public ResponseEntity<StreamingResponseBody> select(@PathVariable String streamId, @PathVariable String symbolId,
10271031
@Valid @RequestBody(required = false) InstrumentRequest select,
1028-
OutputStream outputStream) {
1032+
OutputStream outputStream, JsonBigIntEncoding bigIntEncoding) {
10291033
DXTickStream stream = service.getStream(streamId);
10301034

10311035
if (stream == null)
@@ -1054,7 +1058,7 @@ public ResponseEntity<StreamingResponseBody> select(@PathVariable String streamI
10541058
.contentType(MediaType.APPLICATION_JSON)
10551059
.body(new MessageSource2ResponseStream(
10561060
stream.select(startTime, options, select.types, ids), select.getEndTime(), startIndex, endIndex,
1057-
MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET)
1061+
MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET, bigIntEncoding)
10581062
);
10591063
}
10601064

@@ -1090,14 +1094,15 @@ public ResponseEntity<StreamingResponseBody> select(
10901094
@RequestParam(required = false) Long offset,
10911095
@RequestParam(required = false) Integer rows,
10921096
@RequestParam(required = false) String space,
1093-
@RequestParam(required = false) boolean reverse) throws NoStreamsException {
1097+
@RequestParam(required = false) boolean reverse,
1098+
JsonBigIntEncoding bigIntEncoding) throws NoStreamsException {
10941099
if (TextUtils.isEmpty(streamId))
10951100
throw new NoStreamsException();
10961101

10971102
if (TextUtils.isEmpty(symbolId))
10981103
return ResponseEntity.notFound().build();
10991104

1100-
return select(new String[]{streamId}, new String[]{symbolId}, types, depth, from, to, offset, rows, space, reverse);
1105+
return select(new String[]{streamId}, new String[]{symbolId}, types, depth, from, to, offset, rows, space, reverse, bigIntEncoding);
11011106
}
11021107

11031108
private SelectionOptions getSelectionOption(BaseRequest r) {
@@ -1535,9 +1540,8 @@ public ResponseEntity<StreamDef[]> streams(@RequestParam(required = false, defau
15351540
*/
15361541
@PreAuthorize("hasAnyAuthority('TB_ALLOW_READ', 'TB_ALLOW_WRITE')")
15371542
@RequestMapping(value = "/query", method = {RequestMethod.POST})
1538-
public ResponseEntity<StreamingResponseBody> query(Principal principal, @Valid @RequestBody(required = false) QueryRequest select)
1539-
throws InvalidQueryException, WriteOperationsException {
1540-
1543+
public ResponseEntity<StreamingResponseBody> query(Principal principal, @Valid @RequestBody(required = false) QueryRequest select,
1544+
JsonBigIntEncoding bigIntEncoding) throws InvalidQueryException, WriteOperationsException {
15411545
if (select == null || StringUtils.isEmpty(select.query))
15421546
throw new InvalidQueryException(select == null ? "" : select.query);
15431547

@@ -1559,7 +1563,34 @@ public ResponseEntity<StreamingResponseBody> query(Principal principal, @Valid @
15591563
.body(new MessageSource2ResponseStream(
15601564
service.getConnection().executeQuery(
15611565
select.query, options, null, null, select.getStartTime(Long.MIN_VALUE), select.getEndTime(Long.MIN_VALUE)),
1562-
select.getEndTime(), startIndex, endIndex, MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET));
1566+
select.getEndTime(), startIndex, endIndex, MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET, bigIntEncoding));
1567+
}
1568+
1569+
/**
1570+
* Executes an QQL query and returns the maximum possible number of records
1571+
*/
1572+
@PreAuthorize("hasAnyAuthority('TB_ALLOW_READ', 'TB_ALLOW_WRITE')")
1573+
@RequestMapping(value = "/unlimitedQuery", method = {RequestMethod.POST})
1574+
public ResponseEntity<StreamingResponseBody> unlimitedQuery(Principal principal, @Valid @RequestBody(required = false) QueryRequest select,
1575+
JsonBigIntEncoding bigIntEncoding)
1576+
throws InvalidQueryException, WriteOperationsException {
1577+
1578+
if (select == null || StringUtils.isEmpty(select.query))
1579+
throw new InvalidQueryException(select == null ? "" : select.query);
1580+
if (service.isReadonly() && (select.query.toLowerCase().contains("drop") || select.query.toLowerCase().contains("create")))
1581+
throw new WriteOperationsException("CREATE or DROP");
1582+
if (isDdlQuery(select.query) && !hasAuthority(principal, "TB_ALLOW_WRITE")) {
1583+
throw new AccessDeniedException("TB_ALLOW_WRITE permission required.");
1584+
}
1585+
1586+
SelectionOptions options = getSelectionOption(select);
1587+
LOGGER.info().append("UNLIMITED QUERY: (").append(select.query).append(")").commit();
1588+
return ResponseEntity.ok()
1589+
.contentType(MediaType.APPLICATION_JSON)
1590+
.body(new MessageSource2ResponseStream(
1591+
service.getConnection().executeQuery(
1592+
select.query, options, null, null, select.getStartTime(Long.MIN_VALUE), select.getEndTime(Long.MIN_VALUE)),
1593+
select.getEndTime(), 0, Integer.MAX_VALUE, Integer.MAX_VALUE, bigIntEncoding));
15631594
}
15641595

15651596
private boolean isDdlQuery(String query) {
@@ -1663,8 +1694,8 @@ public Set<ShortFunctionDef> queryFunctionsShort() {
16631694
@PreAuthorize("hasAnyAuthority('TB_ALLOW_READ', 'TB_ALLOW_WRITE')")
16641695
@RequestMapping(value = "/{streamId}/filter", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_JSON_VALUE,
16651696
produces = MediaType.APPLICATION_JSON_VALUE)
1666-
public ResponseEntity<StreamingResponseBody> filter(@PathVariable String streamId, @Valid @RequestBody FilterRequest filter)
1667-
throws UnknownStreamException {
1697+
public ResponseEntity<StreamingResponseBody> filter(@PathVariable String streamId, @Valid @RequestBody FilterRequest filter,
1698+
JsonBigIntEncoding bigIntEncoding) throws UnknownStreamException {
16681699
DXTickStream stream = service.getStream(streamId);
16691700
if (stream == null)
16701701
throw new UnknownStreamException(streamId);
@@ -1697,7 +1728,7 @@ public ResponseEntity<StreamingResponseBody> filter(@PathVariable String streamI
16971728
.contentType(MediaType.APPLICATION_JSON)
16981729
.body(new MessageSource2ResponseStream(service.getConnection()
16991730
.executeQuery(query, options, null, null, startTime), endTime, startIndex, endIndex,
1700-
MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET));
1731+
MAX_NUMBER_OF_RECORDS_PER_REST_RESULTSET, bigIntEncoding));
17011732
}
17021733

17031734
/**

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/controllers/TopicController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.epam.deltix.tbwg.webapp.model.tree.TreeNodeDef;
2929
import com.epam.deltix.tbwg.webapp.services.timebase.MonitorService;
3030
import com.epam.deltix.tbwg.webapp.services.topic.TopicService;
31+
import com.epam.deltix.tbwg.webapp.utils.HeaderAccessorHelper;
32+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncoding;
3133
import com.epam.deltix.tbwg.webapp.websockets.subscription.Subscription;
3234
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionChannel;
3335
import com.epam.deltix.tbwg.webapp.websockets.subscription.SubscriptionController;
@@ -126,8 +128,9 @@ public Subscription onSubscribe(SimpMessageHeaderAccessor header, SubscriptionCh
126128
String topicKey = URLDecoder.decode(extractId(destination), StandardCharsets.UTF_8);
127129
String sessionId = header.getSessionId();
128130
String subscriptionId = header.getSubscriptionId();
131+
JsonBigIntEncoding bigIntEncoding = HeaderAccessorHelper.getJsonBigIntEncoding(header);
129132

130-
monitorService.subscribeTopic(sessionId, subscriptionId, topicKey, channel::sendMessage);
133+
monitorService.subscribeTopic(sessionId, subscriptionId, topicKey, channel::sendMessage, bigIntEncoding);
131134
return () -> monitorService.unsubscribe(sessionId, subscriptionId);
132135
}
133136

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/services/charting/transformations/QqlConversionTransformation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
import com.epam.deltix.qsrv.util.json.JSONRawMessagePrinter;
2121
import com.epam.deltix.tbwg.messages.Message;
2222
import com.epam.deltix.tbwg.webapp.model.charting.line.RawElementDef;
23+
import com.epam.deltix.tbwg.webapp.utils.json.WebGatewayJsonRawMessagePrinterFactory;
2324

2425
import java.util.Collections;
2526

27+
@Deprecated // not implemented on the front-end side
2628
public class QqlConversionTransformation extends AbstractChartTransformation<RawElementDef, RawMessage> {
2729

2830
private final StringBuilder sb = new StringBuilder();
29-
private final JSONRawMessagePrinter rawMessagePrinter = new JSONRawMessagePrinter();
31+
private final JSONRawMessagePrinter rawMessagePrinter = WebGatewayJsonRawMessagePrinterFactory.create();
3032

3133
public QqlConversionTransformation() {
3234
super(Collections.singletonList(RawMessage.class), Collections.singletonList(RawElementDef.class));

java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/services/timebase/MonitorService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@
1616
*/
1717
package com.epam.deltix.tbwg.webapp.services.timebase;
1818

19+
import com.epam.deltix.tbwg.webapp.utils.json.JsonBigIntEncoding;
20+
1921
import java.util.List;
2022
import java.util.function.Consumer;
2123

2224
public interface MonitorService {
2325

2426
void subscribe(String sessionId, String subscriptionId, String key, String qql, long fromTimestamp, List<String> types,
25-
List<String> symbols, Consumer<String> consumer);
27+
List<String> symbols, Consumer<String> consumer, JsonBigIntEncoding bigIntEncoding);
2628

2729
void subscribeTopic(String sessionId, String subscriptionId, String key,
28-
Consumer<String> consumer);
30+
Consumer<String> consumer, JsonBigIntEncoding bigIntEncoding);
2931

3032
void unsubscribe(String sessionId, String subscriptionId);
3133

0 commit comments

Comments
 (0)