|
2 | 2 |
|
3 | 3 | import com.skyflow.config.Credentials; |
4 | 4 | import com.skyflow.config.VaultConfig; |
| 5 | +import com.skyflow.enums.DetectEntities; |
5 | 6 | import com.skyflow.errors.ErrorCode; |
6 | 7 | import com.skyflow.errors.ErrorMessage; |
7 | 8 | import com.skyflow.errors.SkyflowException; |
|
12 | 13 | import com.skyflow.generated.rest.resources.records.requests.RecordServiceBatchOperationBody; |
13 | 14 | import com.skyflow.generated.rest.resources.records.requests.RecordServiceInsertRecordBody; |
14 | 15 | import com.skyflow.generated.rest.resources.records.requests.RecordServiceUpdateRecordBody; |
| 16 | +import com.skyflow.generated.rest.resources.strings.StringsClient; |
| 17 | +import com.skyflow.generated.rest.resources.strings.requests.DeidentifyStringRequest; |
| 18 | +import com.skyflow.generated.rest.resources.strings.requests.ReidentifyStringRequest; |
| 19 | +import com.skyflow.generated.rest.resources.strings.types.ReidentifyStringRequestFormat; |
15 | 20 | import com.skyflow.generated.rest.resources.tokens.TokensClient; |
16 | 21 | import com.skyflow.generated.rest.resources.tokens.requests.V1DetokenizePayload; |
17 | 22 | import com.skyflow.generated.rest.resources.tokens.requests.V1TokenizePayload; |
18 | 23 | import com.skyflow.generated.rest.types.*; |
| 24 | +import com.skyflow.generated.rest.types.Transformations; |
19 | 25 | import com.skyflow.logs.InfoLogs; |
20 | 26 | import com.skyflow.serviceaccount.util.Token; |
21 | 27 | import com.skyflow.utils.Constants; |
|
24 | 30 | import com.skyflow.utils.validations.Validations; |
25 | 31 | import com.skyflow.vault.data.InsertRequest; |
26 | 32 | import com.skyflow.vault.data.UpdateRequest; |
| 33 | +import com.skyflow.vault.detect.*; |
27 | 34 | import com.skyflow.vault.tokens.ColumnValue; |
28 | 35 | import com.skyflow.vault.tokens.DetokenizeData; |
29 | 36 | import com.skyflow.vault.tokens.DetokenizeRequest; |
30 | 37 | import com.skyflow.vault.tokens.TokenizeRequest; |
31 | 38 | import io.github.cdimascio.dotenv.Dotenv; |
32 | 39 | import io.github.cdimascio.dotenv.DotenvException; |
33 | 40 |
|
34 | | -import java.util.ArrayList; |
35 | | -import java.util.HashMap; |
36 | | -import java.util.List; |
| 41 | +import java.util.*; |
| 42 | +import java.util.stream.Collectors; |
| 43 | + |
37 | 44 |
|
38 | 45 | public class VaultClient { |
39 | 46 | private final VaultConfig vaultConfig; |
@@ -61,6 +68,10 @@ protected TokensClient getTokensApi() { |
61 | 68 | return this.apiClient.tokens(); |
62 | 69 | } |
63 | 70 |
|
| 71 | + protected StringsClient getDetectTextApi() { |
| 72 | + return this.apiClient.strings(); |
| 73 | + } |
| 74 | + |
64 | 75 | protected QueryClient getQueryApi() { |
65 | 76 | return this.apiClient.query(); |
66 | 77 | } |
@@ -209,6 +220,168 @@ protected void setBearerToken() throws SkyflowException { |
209 | 220 | this.apiClient = this.apiClientBuilder.build(); |
210 | 221 | } |
211 | 222 |
|
| 223 | + protected DeidentifyTextResponse getDeIdentifyTextResponse(DeidentifyStringResponse deidentifyStringResponse) { |
| 224 | + List<EntityInfo> entities = deidentifyStringResponse.getEntities() != null |
| 225 | + ? deidentifyStringResponse.getEntities().stream() |
| 226 | + .map(this::convertDetectedEntityToEntityInfo) |
| 227 | + .collect(Collectors.toList()) |
| 228 | + : null; |
| 229 | + |
| 230 | + return new DeidentifyTextResponse( |
| 231 | + deidentifyStringResponse.getProcessedText(), |
| 232 | + entities, |
| 233 | + deidentifyStringResponse.getWordCount(), |
| 234 | + deidentifyStringResponse.getCharacterCount() |
| 235 | + ); |
| 236 | + } |
| 237 | + |
| 238 | + protected DeidentifyStringRequest getDeidentifyStringRequest(DeidentifyTextRequest deIdentifyTextRequest, String vaultId) throws SkyflowException { |
| 239 | + List<DetectEntities> entities = deIdentifyTextRequest.getEntities(); |
| 240 | + |
| 241 | + List<EntityType> mappedEntityTypes = null; |
| 242 | + if (entities != null) { |
| 243 | + mappedEntityTypes = deIdentifyTextRequest.getEntities().stream() |
| 244 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 245 | + .collect(Collectors.toList()); |
| 246 | + } |
| 247 | + |
| 248 | + TokenFormat tokenFormat = deIdentifyTextRequest.getTokenFormat(); |
| 249 | + |
| 250 | + Optional<List<EntityType>> vaultToken = Optional.empty(); |
| 251 | + Optional<List<EntityType>> entityTypes = Optional.empty(); |
| 252 | + Optional<List<EntityType>> entityUniqueCounter = Optional.empty(); |
| 253 | + Optional<List<String>> allowRegex = Optional.ofNullable(deIdentifyTextRequest.getAllowRegexList()); |
| 254 | + Optional<List<String>> restrictRegex = Optional.ofNullable(deIdentifyTextRequest.getRestrictRegexList()); |
| 255 | + Optional<Transformations> transformations = Optional.ofNullable(getTransformations(deIdentifyTextRequest.getTransformations())); |
| 256 | + |
| 257 | + if (tokenFormat != null) { |
| 258 | + if (tokenFormat.getVaultToken() != null && !tokenFormat.getVaultToken().isEmpty()) { |
| 259 | + vaultToken = Optional.of(tokenFormat.getVaultToken().stream() |
| 260 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 261 | + .collect(Collectors.toList())); |
| 262 | + } |
| 263 | + |
| 264 | + if (tokenFormat.getEntityOnly() != null && !tokenFormat.getEntityOnly().isEmpty()) { |
| 265 | + entityTypes = Optional.of(tokenFormat.getEntityOnly().stream() |
| 266 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 267 | + .collect(Collectors.toList())); |
| 268 | + } |
| 269 | + |
| 270 | + if (tokenFormat.getEntityUniqueCounter() != null && !tokenFormat.getEntityUniqueCounter().isEmpty()) { |
| 271 | + entityUniqueCounter = Optional.of(tokenFormat.getEntityUniqueCounter().stream() |
| 272 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 273 | + .collect(Collectors.toList())); |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + TokenType tokenType = TokenType.builder() |
| 278 | + .vaultToken(vaultToken) |
| 279 | + .entityOnly(entityTypes) |
| 280 | + .entityUnqCounter(entityUniqueCounter) |
| 281 | + .build(); |
| 282 | + |
| 283 | + |
| 284 | + return DeidentifyStringRequest.builder() |
| 285 | + .vaultId(vaultId) |
| 286 | + .text(deIdentifyTextRequest.getText()) |
| 287 | + .entityTypes(mappedEntityTypes) |
| 288 | + .tokenType(tokenType) |
| 289 | + .allowRegex(allowRegex) |
| 290 | + .restrictRegex(restrictRegex) |
| 291 | + .transformations(transformations) |
| 292 | + .build(); |
| 293 | + } |
| 294 | + |
| 295 | + protected ReidentifyStringRequest getReidentifyStringRequest(ReidentifyTextRequest reidentifyTextRequest, String vaultId) throws SkyflowException { |
| 296 | + List<EntityType> maskEntities = null; |
| 297 | + List<EntityType> redactedEntities = null; |
| 298 | + List<EntityType> plaintextEntities = null; |
| 299 | + |
| 300 | + if (reidentifyTextRequest.getMaskedEntities() != null) { |
| 301 | + maskEntities = reidentifyTextRequest.getMaskedEntities().stream() |
| 302 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 303 | + .collect(Collectors.toList()); |
| 304 | + } |
| 305 | + |
| 306 | + if (reidentifyTextRequest.getPlainTextEntities() != null) { |
| 307 | + plaintextEntities = reidentifyTextRequest.getPlainTextEntities().stream() |
| 308 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 309 | + .collect(Collectors.toList()); |
| 310 | + } |
| 311 | + |
| 312 | + if (reidentifyTextRequest.getRedactedEntities() != null) { |
| 313 | + redactedEntities = reidentifyTextRequest.getRedactedEntities().stream() |
| 314 | + .map(detectEntity -> EntityType.valueOf(detectEntity.name())) |
| 315 | + .collect(Collectors.toList()); |
| 316 | + } |
| 317 | + |
| 318 | + ReidentifyStringRequestFormat reidentifyStringRequestFormat = ReidentifyStringRequestFormat.builder() |
| 319 | + .masked(maskEntities) |
| 320 | + .plaintext(plaintextEntities) |
| 321 | + .redacted(redactedEntities) |
| 322 | + .build(); |
| 323 | + |
| 324 | + |
| 325 | + return ReidentifyStringRequest.builder() |
| 326 | + .text(reidentifyTextRequest.getText()) |
| 327 | + .vaultId(vaultId) |
| 328 | + .format(reidentifyStringRequestFormat) |
| 329 | + .build(); |
| 330 | + } |
| 331 | + |
| 332 | + |
| 333 | + private EntityInfo convertDetectedEntityToEntityInfo(DetectedEntity detectedEntity) { |
| 334 | + TextIndex textIndex = new TextIndex( |
| 335 | + detectedEntity.getLocation().get().getStartIndex().orElse(0), |
| 336 | + detectedEntity.getLocation().get().getEndIndex().orElse(0) |
| 337 | + ); |
| 338 | + TextIndex processedIndex = new TextIndex( |
| 339 | + detectedEntity.getLocation().get().getStartIndexProcessed().orElse(0), |
| 340 | + detectedEntity.getLocation().get().getEndIndexProcessed().orElse(0) |
| 341 | + ); |
| 342 | + |
| 343 | + Map<String, Float> entityScores = detectedEntity.getEntityScores() |
| 344 | + .map(doubleMap -> doubleMap.entrySet().stream() |
| 345 | + .collect(Collectors.toMap( |
| 346 | + Map.Entry::getKey, |
| 347 | + entry -> entry.getValue().floatValue() |
| 348 | + ))) |
| 349 | + .orElse(Collections.emptyMap()); |
| 350 | + |
| 351 | + |
| 352 | + return new EntityInfo( |
| 353 | + detectedEntity.getToken().orElse(""), |
| 354 | + detectedEntity.getValue().orElse(""), |
| 355 | + textIndex, |
| 356 | + processedIndex, |
| 357 | + detectedEntity.getEntityType().orElse(""), |
| 358 | + entityScores); |
| 359 | + } |
| 360 | + |
| 361 | + |
| 362 | + private Transformations getTransformations(com.skyflow.vault.detect.Transformations transformations) { |
| 363 | + if (transformations == null || transformations.getShiftDates() == null) { |
| 364 | + return null; |
| 365 | + } |
| 366 | + |
| 367 | + List<TransformationsShiftDatesEntityTypesItem> entityTypes = null; |
| 368 | + if (!transformations.getShiftDates().getEntities().isEmpty()) { |
| 369 | + entityTypes = transformations.getShiftDates().getEntities().stream() |
| 370 | + .map(entity -> TransformationsShiftDatesEntityTypesItem.valueOf(entity.name())) |
| 371 | + .collect(Collectors.toList()); |
| 372 | + } else { |
| 373 | + entityTypes = Collections.emptyList(); |
| 374 | + } |
| 375 | + |
| 376 | + return Transformations.builder() |
| 377 | + .shiftDates(TransformationsShiftDates.builder() |
| 378 | + .maxDays(transformations.getShiftDates().getMax()) |
| 379 | + .minDays(transformations.getShiftDates().getMin()) |
| 380 | + .entityTypes(entityTypes) |
| 381 | + .build()) |
| 382 | + .build(); |
| 383 | + } |
| 384 | + |
212 | 385 | private void setApiKey() { |
213 | 386 | if (apiKey == null) { |
214 | 387 | apiKey = this.finalCredentials.getApiKey(); |
|
0 commit comments