Skip to content

Commit f52ddef

Browse files
authored
Merge pull request #43 from fingerprintjs/feat/open-api-v3.6.0
OpenAPI schema sync (v3.6.0)
2 parents 548842b + cb8fc3e commit f52ddef

18 files changed

Lines changed: 306 additions & 13 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'java-sdk': minor
3+
---
4+
5+
Add `source` field to `Event` to identify how the event was generated (`device` or `edge`)

.schema-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v3.5.1
1+
v3.6.0

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ Class | Method | HTTP request | Description
345345
- [EventRuleActionAllow](docs/EventRuleActionAllow.md)
346346
- [EventRuleActionBlock](docs/EventRuleActionBlock.md)
347347
- [EventSearch](docs/EventSearch.md)
348+
- [EventSource](docs/EventSource.md)
348349
- [EventUpdate](docs/EventUpdate.md)
349350
- [FontPreferences](docs/FontPreferences.md)
350351
- [Geolocation](docs/Geolocation.md)

docs/Event.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Contains results from Fingerprint Identification and all active Smart Signals. S
1010
|------------ | ------------- | ------------- | -------------|
1111
|**eventId** | **String** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | |
1212
|**timestamp** | **Long** | Timestamp of the event with millisecond precision in Unix time. | |
13+
|**source** | [**EventSource**](EventSource.md) | | [optional] |
1314
|**incrementalIdentificationStatus** | [**IncrementalIdentificationStatus**](IncrementalIdentificationStatus.md) | | [optional] |
1415
|**linkedId** | **String** | A customer-provided id that was sent with the request. | [optional] |
1516
|**environmentId** | **String** | Environment Id of the event. | [optional] |

docs/EventSource.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
3+
# EventSource
4+
Identifies how the event was generated.
5+
- `device` - the event was generated by the JS agent or a mobile SDK running on an end-user device.
6+
- `edge` - the event was generated by the Automation Intelligence API (`/edge` endpoint), analyzing a request intercepted at the edge.
7+
8+
9+
## Enum
10+
11+
12+
* `DEVICE` (value: `"device"`)
13+
14+
* `EDGE` (value: `"edge"`)
15+
16+
* `UNSUPPORTED_VALUE_SDK_UPGRADE_REQUIRED` (value: `"unsupported_value_sdk_upgrade_required"`)
17+
18+
19+

examples/src/main/java/com/fingerprint/example/FunctionalTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,16 @@ public static void main(String... args) {
122122
System.exit(1);
123123
}
124124

125-
api.getEvent(oldRequestId);
125+
try {
126+
api.getEvent(oldRequestId);
127+
} catch (ApiException e) {
128+
System.err.println(
129+
"Exception when trying to request old event \""
130+
+ oldRequestId
131+
+ "\":"
132+
+ e.getMessage());
133+
System.exit(1);
134+
}
126135
System.out.println("Old events are good");
127136
} catch (ApiException e) {
128137
System.err.println("Exception when trying to read old data:" + e.getMessage());

res/fingerprint-server-api.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,19 @@ components:
11781178
format: int64
11791179
examples:
11801180
- 1708102555327
1181+
EventSource:
1182+
type: string
1183+
description: >
1184+
Identifies how the event was generated.
1185+
1186+
- `device` - the event was generated by the JS agent or a mobile SDK
1187+
running on an end-user device.
1188+
1189+
- `edge` - the event was generated by the Automation Intelligence API
1190+
(`/edge` endpoint), analyzing a request intercepted at the edge.
1191+
enum:
1192+
- device
1193+
- edge
11811194
Url:
11821195
type: string
11831196
examples:
@@ -3084,6 +3097,12 @@ components:
30843097
- android
30853098
- ios
30863099
- browser
3100+
source:
3101+
$ref: '#/components/schemas/EventSource'
3102+
x-platforms:
3103+
- android
3104+
- ios
3105+
- browser
30873106
incremental_identification_status:
30883107
$ref: '#/components/schemas/IncrementalIdentificationStatus'
30893108
x-platforms:

sdk/src/main/java/com/fingerprint/v4/model/Event.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
@JsonPropertyOrder({
2828
Event.JSON_PROPERTY_EVENT_ID,
2929
Event.JSON_PROPERTY_TIMESTAMP,
30+
Event.JSON_PROPERTY_SOURCE,
3031
Event.JSON_PROPERTY_INCREMENTAL_IDENTIFICATION_STATUS,
3132
Event.JSON_PROPERTY_LINKED_ID,
3233
Event.JSON_PROPERTY_ENVIRONMENT_ID,
@@ -100,6 +101,9 @@ public class Event {
100101
public static final String JSON_PROPERTY_TIMESTAMP = "timestamp";
101102
@jakarta.annotation.Nonnull private Long timestamp;
102103

104+
public static final String JSON_PROPERTY_SOURCE = "source";
105+
@jakarta.annotation.Nullable private EventSource source;
106+
103107
public static final String JSON_PROPERTY_INCREMENTAL_IDENTIFICATION_STATUS =
104108
"incremental_identification_status";
105109

@@ -337,6 +341,28 @@ public void setTimestamp(@jakarta.annotation.Nonnull Long timestamp) {
337341
this.timestamp = timestamp;
338342
}
339343

344+
public Event source(@jakarta.annotation.Nullable EventSource source) {
345+
this.source = source;
346+
return this;
347+
}
348+
349+
/**
350+
* Get source
351+
* @return source
352+
*/
353+
@jakarta.annotation.Nullable
354+
@JsonProperty(value = JSON_PROPERTY_SOURCE, required = false)
355+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
356+
public EventSource getSource() {
357+
return source;
358+
}
359+
360+
@JsonProperty(value = JSON_PROPERTY_SOURCE, required = false)
361+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
362+
public void setSource(@jakarta.annotation.Nullable EventSource source) {
363+
this.source = source;
364+
}
365+
340366
public Event incrementalIdentificationStatus(
341367
@jakarta.annotation.Nullable
342368
IncrementalIdentificationStatus incrementalIdentificationStatus) {
@@ -1751,6 +1777,7 @@ public boolean equals(Object o) {
17511777
Event event = (Event) o;
17521778
return Objects.equals(this.eventId, event.eventId)
17531779
&& Objects.equals(this.timestamp, event.timestamp)
1780+
&& Objects.equals(this.source, event.source)
17541781
&& Objects.equals(
17551782
this.incrementalIdentificationStatus, event.incrementalIdentificationStatus)
17561783
&& Objects.equals(this.linkedId, event.linkedId)
@@ -1821,6 +1848,7 @@ public int hashCode() {
18211848
return Objects.hash(
18221849
eventId,
18231850
timestamp,
1851+
source,
18241852
incrementalIdentificationStatus,
18251853
linkedId,
18261854
environmentId,
@@ -1891,6 +1919,7 @@ public String toString() {
18911919
sb.append("class Event {\n");
18921920
sb.append(" eventId: ").append(toIndentedString(eventId)).append("\n");
18931921
sb.append(" timestamp: ").append(toIndentedString(timestamp)).append("\n");
1922+
sb.append(" source: ").append(toIndentedString(source)).append("\n");
18941923
sb.append(" incrementalIdentificationStatus: ")
18951924
.append(toIndentedString(incrementalIdentificationStatus))
18961925
.append("\n");
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Server API
3+
* Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts.
4+
*
5+
* The version of the OpenAPI document: 4
6+
* Contact: support@fingerprint.com
7+
*
8+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9+
* https://openapi-generator.tech
10+
* Do not edit the class manually.
11+
*/
12+
13+
package com.fingerprint.v4.model;
14+
15+
import com.fasterxml.jackson.annotation.JsonCreator;
16+
import com.fasterxml.jackson.annotation.JsonValue;
17+
18+
/**
19+
* Identifies how the event was generated. - `device` - the event was generated by the JS agent or a mobile SDK running on an end-user device. - `edge` - the event was generated by the Automation Intelligence API (`/edge` endpoint), analyzing a request intercepted at the edge.
20+
*/
21+
public enum EventSource {
22+
DEVICE("device"),
23+
24+
EDGE("edge"),
25+
26+
UNSUPPORTED_VALUE_SDK_UPGRADE_REQUIRED("unsupported_value_sdk_upgrade_required");
27+
28+
private String value;
29+
30+
EventSource(String value) {
31+
this.value = value;
32+
}
33+
34+
@JsonValue
35+
public String getValue() {
36+
return value;
37+
}
38+
39+
@Override
40+
public String toString() {
41+
return String.valueOf(value);
42+
}
43+
44+
@JsonCreator
45+
public static EventSource fromValue(String value) {
46+
for (EventSource b : EventSource.values()) {
47+
if (b.value.equals(value)) {
48+
return b;
49+
}
50+
}
51+
return UNSUPPORTED_VALUE_SDK_UPGRADE_REQUIRED;
52+
}
53+
}

sdk/src/test/java/com/fingerprint/v4/SerializationTest.java

Lines changed: 100 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
package com.fingerprint.v4;
22

33
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
45
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
6+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
7+
import static org.junit.jupiter.api.Assertions.assertNotNull;
58

69
import com.fasterxml.jackson.databind.ObjectMapper;
710
import com.fasterxml.jackson.databind.SerializationFeature;
811
import com.fasterxml.jackson.databind.node.ObjectNode;
912
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
13+
import com.fingerprint.v4.model.ErrorCode;
14+
import com.fingerprint.v4.model.ErrorResponse;
1015
import com.fingerprint.v4.model.Event;
1116
import com.fingerprint.v4.model.EventRuleAction;
1217
import com.fingerprint.v4.sdk.JSON;
18+
import java.io.File;
1319
import java.io.IOException;
1420
import java.io.InputStream;
21+
import java.net.URISyntaxException;
22+
import java.net.URL;
23+
import java.util.Arrays;
24+
import java.util.List;
25+
import java.util.function.Predicate;
26+
import java.util.stream.Collectors;
27+
import java.util.stream.Stream;
28+
import org.junit.jupiter.api.DynamicTest;
1529
import org.junit.jupiter.api.Test;
30+
import org.junit.jupiter.api.TestFactory;
1631
import org.junit.jupiter.api.TestInstance;
1732

1833
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
1934
public class SerializationTest {
2035

36+
private static final String ERRORS_DIR = "mocks/errors";
37+
private static final String EVENTS_DIR = "mocks/events";
38+
2139
private InputStream getFileAsIOStream(final String fileName) {
2240
InputStream ioStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
2341

@@ -35,17 +53,6 @@ private static ObjectMapper getMapper() {
3553
return mapper;
3654
}
3755

38-
@Test
39-
public void deserializeSerializeEvent() throws IOException {
40-
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();
41-
Event event =
42-
sdkObjectMapper.readValue(
43-
getFileAsIOStream("mocks/events/get_event_200.json"), Event.class);
44-
45-
ObjectMapper springLikeObjectMapper = getMapper();
46-
springLikeObjectMapper.writeValueAsString(event);
47-
}
48-
4956
@Test
5057
public void deserializeEventWithUnknownBotResultValue() throws IOException {
5158
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();
@@ -96,4 +103,86 @@ public void deserializeEventWithUnknownRuleActionTypeValue() throws IOException
96103

97104
assertInstanceOf(EventRuleAction.UnknownEventRuleAction.class, event.getRuleAction());
98105
}
106+
107+
@TestFactory
108+
public Stream<DynamicTest> deserializeErrorResponses() {
109+
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();
110+
111+
return listMockFileNames(ERRORS_DIR, name -> true).stream()
112+
.map(
113+
fileName ->
114+
DynamicTest.dynamicTest(
115+
fileName,
116+
() -> {
117+
String resource = ERRORS_DIR + "/" + fileName;
118+
119+
ObjectNode errorNode =
120+
sdkObjectMapper.readValue(getFileAsIOStream(resource), ObjectNode.class);
121+
ErrorResponse errorResponse =
122+
sdkObjectMapper.readValue(
123+
getFileAsIOStream(resource), ErrorResponse.class);
124+
125+
assertNotNull(errorResponse.getError());
126+
assertNotEquals(
127+
ErrorCode.UNSUPPORTED_VALUE_SDK_UPGRADE_REQUIRED,
128+
errorResponse.getError().getCode(),
129+
"Unknown error code in " + resource);
130+
assertEquals(
131+
errorNode.at("/error/code").asText(),
132+
errorResponse.getError().getCode().getValue());
133+
assertEquals(
134+
errorNode.at("/error/message").asText(),
135+
errorResponse.getError().getMessage());
136+
137+
getMapper().writeValueAsString(errorResponse);
138+
}));
139+
}
140+
141+
@TestFactory
142+
public Stream<DynamicTest> deserializeSerializeEvents() {
143+
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();
144+
145+
return listMockFileNames(EVENTS_DIR, name -> name.startsWith("get_event")).stream()
146+
.map(
147+
fileName ->
148+
DynamicTest.dynamicTest(
149+
fileName,
150+
() -> {
151+
String resource = EVENTS_DIR + "/" + fileName;
152+
153+
ObjectNode eventNode =
154+
sdkObjectMapper.readValue(getFileAsIOStream(resource), ObjectNode.class);
155+
Event event =
156+
sdkObjectMapper.readValue(getFileAsIOStream(resource), Event.class);
157+
158+
assertEquals(eventNode.get("event_id").asText(), event.getEventId());
159+
assertEquals(
160+
eventNode.get("timestamp").asLong(), event.getTimestamp().longValue());
161+
162+
getMapper().writeValueAsString(event);
163+
}));
164+
}
165+
166+
private List<String> listMockFileNames(String directoryName, Predicate<String> fileNameFilter) {
167+
URL directory = this.getClass().getClassLoader().getResource(directoryName);
168+
169+
if (directory == null) {
170+
throw new IllegalStateException(directoryName + " is not found");
171+
}
172+
173+
File[] files;
174+
try {
175+
files =
176+
new File(directory.toURI())
177+
.listFiles((dir, name) -> name.endsWith(".json") && fileNameFilter.test(name));
178+
} catch (URISyntaxException e) {
179+
throw new IllegalStateException(e);
180+
}
181+
182+
if (files == null || files.length == 0) {
183+
throw new IllegalStateException("No mocks found in " + directoryName);
184+
}
185+
186+
return Arrays.stream(files).map(File::getName).sorted().collect(Collectors.toList());
187+
}
99188
}

0 commit comments

Comments
 (0)