@@ -107,16 +107,32 @@ public class UIDOperatorVerticle extends AbstractVerticle {
107107 private final UidInstanceIdProvider uidInstanceIdProvider ;
108108 protected IUIDOperatorService idService ;
109109
110+ // uid2_operator_identity_map_inputs
110111 private final Map <String , DistributionSummary > _identityMapMetricSummaries = new HashMap <>();
112+ // uid2_operator_identity_map_services_inputs
113+ private final Map <String , DistributionSummary > _identityMapServicesMetricSummaries = new HashMap <>();
114+ // uid2_token_refresh_duration_seconds
111115 private final Map <Tuple .Tuple2 <String , Boolean >, DistributionSummary > _refreshDurationMetricSummaries = new HashMap <>();
116+ // uid2_advertising_token_expired_on_refresh_total
112117 private final Map <Tuple .Tuple3 <String , Boolean , Boolean >, Counter > _advertisingTokenExpiryStatus = new HashMap <>();
118+ // uid2_token_generate_tcf_usage_total
113119 private final Map <String , Counter > _tokenGenerateTCFUsage = new HashMap <>();
120+ // uid2_operator_identity_map_unmapped_total (reason=invalid, reason=optout)
114121 private final Map <String , Tuple .Tuple2 <Counter , Counter >> _identityMapUnmappedIdentifiers = new HashMap <>();
122+ // uid2_operator_identity_map_services_unmapped_total (reason=invalid, reason=optout)
123+ private final Map <String , Tuple .Tuple2 <Counter , Counter >> _identityMapServicesUnmappedIdentifiers = new HashMap <>();
124+ // uid2_operator_identity_map_unmapped_requests_total
115125 private final Map <String , Counter > _identityMapRequestWithUnmapped = new HashMap <>();
126+ // uid2_client_sdk_versions_total
116127 private final Map <Tuple .Tuple2 <String , String >, Counter > _clientVersions = new HashMap <>();
128+ // uid2_token_validate_total
117129 private final Map <Tuple .Tuple2 <String , String >, Counter > _tokenValidateCounters = new HashMap <>();
118130
119- private final Map <String , DistributionSummary > optOutStatusCounters = new HashMap <>();
131+ // uid2_operator_optout_status_input_size
132+ private final Map <String , DistributionSummary > optOutStatusInputSizeCounters = new HashMap <>();
133+ // uid2_operator_optout_status_optout_size
134+ private final Map <String , DistributionSummary > optOutStatusOptOutSizeCounters = new HashMap <>();
135+
120136 private final IdentityScope identityScope ;
121137 private final V2PayloadHandler encryptedPayloadHandler ;
122138 private final boolean phoneSupport ;
@@ -1097,17 +1113,18 @@ private boolean isTokenInputValid(InputUtil.InputVal input, RoutingContext rc) {
10971113 return true ;
10981114 }
10991115
1100- private JsonObject handleIdentityMapCommon (RoutingContext rc , InputUtil . InputVal [] inputList ) {
1116+ private JsonObject processIdentityMapV2Response (RoutingContext rc , IdentityMapV2Input v2Input ) {
11011117 RuntimeConfig config = getConfigFromRc (rc );
11021118 IdentityEnvironment env = config .getIdentityEnvironment ();
1119+ InputUtil .InputVal [] inputList = v2Input .inputList ();
11031120
11041121 final Instant now = Instant .now ();
11051122 final JsonArray mapped = new JsonArray ();
11061123 final JsonArray unmapped = new JsonArray ();
1107- final int count = inputList .length ;
1124+ final int inputCount = inputList .length ;
11081125 int invalidCount = 0 ;
11091126 int optoutCount = 0 ;
1110- for (int i = 0 ; i < count ; ++i ) {
1127+ for (int i = 0 ; i < inputCount ; ++i ) {
11111128 final InputUtil .InputVal input = inputList [i ];
11121129 if (input != null && input .isValid ()) {
11131130 final MappedIdentity mappedIdentity = idService .mapIdentity (
@@ -1138,7 +1155,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal
11381155 }
11391156 }
11401157
1141- recordIdentityMapStats (rc , inputList . length , invalidCount , optoutCount );
1158+ recordIdentityMapStats (rc , Map . of ( v2Input . diiType (), inputCount ) , invalidCount , optoutCount );
11421159
11431160 final JsonObject resp = new JsonObject ();
11441161 resp .put ("mapped" , mapped );
@@ -1154,12 +1171,12 @@ private JsonObject processIdentityMapV3Response(RoutingContext rc, Map<String, I
11541171 final JsonObject mappedResponse = new JsonObject ();
11551172 int invalidCount = 0 ;
11561173 int optoutCount = 0 ;
1157- int inputTotalCount = 0 ;
1174+ Map < String , Integer > diiTypeCounts = new HashMap <>() ;
11581175
11591176 for (Map .Entry <String , InputUtil .InputVal []> identityType : input .entrySet ()) {
11601177 JsonArray mappedIdentityList = new JsonArray ();
11611178 final InputUtil .InputVal [] rawIdentityList = identityType .getValue ();
1162- inputTotalCount += rawIdentityList .length ;
1179+ diiTypeCounts . put ( identityType . getKey (), rawIdentityList .length ) ;
11631180
11641181 for (final InputUtil .InputVal rawId : rawIdentityList ) {
11651182 final JsonObject resp = new JsonObject ();
@@ -1187,7 +1204,7 @@ private JsonObject processIdentityMapV3Response(RoutingContext rc, Map<String, I
11871204 mappedResponse .put (identityType .getKey (), mappedIdentityList );
11881205 }
11891206
1190- recordIdentityMapStats (rc , inputTotalCount , invalidCount , optoutCount );
1207+ recordIdentityMapStats (rc , diiTypeCounts , invalidCount , optoutCount );
11911208
11921209 return mappedResponse ;
11931210 }
@@ -1207,61 +1224,61 @@ private void handleIdentityMapV2(RoutingContext rc) {
12071224 final String apiContact = RoutingContextUtil .getApiContact (rc , clientKeyProvider );
12081225 recordOperatorServedSdkUsage (rc , siteId , apiContact , rc .request ().headers ().get (Const .Http .ClientVersionHeader ));
12091226
1210- final InputUtil . InputVal [] inputList = getIdentityMapV2Input (rc );
1211- if (inputList == null ) {
1227+ final IdentityMapV2Input v2Input = getIdentityMapV2Input (rc );
1228+ if (v2Input == null ) {
12121229 ResponseUtil .LogInfoAndSend400Response (rc , this .phoneSupport ? ERROR_INVALID_INPUT_WITH_PHONE_SUPPORT : ERROR_INVALID_INPUT_EMAIL_MISSING );
12131230 return ;
12141231 }
12151232
12161233 if (!validateServiceLink (rc )) { return ; }
12171234
1218- final JsonObject resp = handleIdentityMapCommon (rc , inputList );
1235+ final JsonObject resp = processIdentityMapV2Response (rc , v2Input );
12191236 ResponseUtil .SuccessV2 (rc , resp );
12201237 } catch (Exception e ) {
12211238 ResponseUtil .LogErrorAndSendResponse (ResponseStatus .UnknownError , 500 , rc , "Unknown error while mapping identity v2" , e );
12221239 }
12231240 }
12241241
1225- private InputUtil . InputVal [] getIdentityMapV2Input (RoutingContext rc ) {
1242+ private IdentityMapV2Input getIdentityMapV2Input (RoutingContext rc ) {
12261243 final JsonObject obj = (JsonObject ) rc .data ().get ("request" );
12271244
1228- Supplier <InputUtil . InputVal []> getInputList = null ;
1245+ Supplier <IdentityMapV2Input > getV2Request = null ;
12291246 final JsonArray emails = JsonParseUtils .parseArray (obj , "email" , rc );
12301247 if (emails != null && !emails .isEmpty ()) {
1231- getInputList = () -> createInputList (emails , IdentityType .Email , InputUtil .IdentityInputType .Raw );
1248+ getV2Request = () -> new IdentityMapV2Input ( "email" , createInputList (emails , IdentityType .Email , InputUtil .IdentityInputType .Raw ) );
12321249 }
12331250
12341251 final JsonArray emailHashes = JsonParseUtils .parseArray (obj , "email_hash" , rc );
12351252 if (emailHashes != null && !emailHashes .isEmpty ()) {
1236- if (getInputList != null ) {
1253+ if (getV2Request != null ) {
12371254 return null ; // only one type of input is allowed
12381255 }
1239- getInputList = () -> createInputList (emailHashes , IdentityType .Email , InputUtil .IdentityInputType .Hash );
1256+ getV2Request = () -> new IdentityMapV2Input ( "email_hash" , createInputList (emailHashes , IdentityType .Email , InputUtil .IdentityInputType .Hash ) );
12401257 }
12411258
12421259 final JsonArray phones = this .phoneSupport ? JsonParseUtils .parseArray (obj ,"phone" , rc ) : null ;
12431260 if (phones != null && !phones .isEmpty ()) {
1244- if (getInputList != null ) {
1261+ if (getV2Request != null ) {
12451262 return null ; // only one type of input is allowed
12461263 }
1247- getInputList = () -> createInputList (phones , IdentityType .Phone , InputUtil .IdentityInputType .Raw );
1264+ getV2Request = () -> new IdentityMapV2Input ( "phone" , createInputList (phones , IdentityType .Phone , InputUtil .IdentityInputType .Raw ) );
12481265 }
12491266
12501267 final JsonArray phoneHashes = this .phoneSupport ? JsonParseUtils .parseArray (obj ,"phone_hash" , rc ) : null ;
12511268 if (phoneHashes != null && !phoneHashes .isEmpty ()) {
1252- if (getInputList != null ) {
1269+ if (getV2Request != null ) {
12531270 return null ; // only one type of input is allowed
12541271 }
1255- getInputList = () -> createInputList (phoneHashes , IdentityType .Phone , InputUtil .IdentityInputType .Hash );
1272+ getV2Request = () -> new IdentityMapV2Input ( "phone_hash" , createInputList (phoneHashes , IdentityType .Phone , InputUtil .IdentityInputType .Hash ) );
12561273 }
12571274
12581275 if (emails == null && emailHashes == null && phones == null && phoneHashes == null ) {
12591276 return null ;
12601277 }
12611278
1262- return getInputList == null ?
1263- createInputList (null , IdentityType .Email , InputUtil .IdentityInputType .Raw ) : // handle empty array
1264- getInputList .get ();
1279+ return getV2Request == null ?
1280+ new IdentityMapV2Input ( "email" , createInputList (null , IdentityType .Email , InputUtil .IdentityInputType .Raw ) ) : // handle empty array
1281+ getV2Request .get ();
12651282 }
12661283
12671284 private void handleIdentityMapV3 (RoutingContext rc ) {
@@ -1317,71 +1334,92 @@ private static String getApiContact(RoutingContext rc) {
13171334 return apiContact ;
13181335 }
13191336
1320- private void recordIdentityMapStats (RoutingContext rc , int inputCount , int invalidCount , int optoutCount ) {
1337+ private void recordIdentityMapStats (RoutingContext rc , Map < String , Integer > diiTypeCounts , int invalidCount , int optoutCount ) {
13211338 String apiContact = getApiContact (rc );
1339+ String path = rc .request ().path ();
1340+
1341+ for (Map .Entry <String , Integer > entry : diiTypeCounts .entrySet ()) {
1342+ String diiType = entry .getKey ();
1343+ int count = entry .getValue ();
1344+ if (count > 0 ) {
1345+ String cacheKey = apiContact + "|" + path + "|" + diiType ;
1346+ DistributionSummary ds = _identityMapMetricSummaries .computeIfAbsent (cacheKey , k -> DistributionSummary
1347+ .builder ("uid2_operator_identity_map_inputs" )
1348+ .description ("number of identifiers passed to identity map endpoint" )
1349+ .tags ("api_contact" , apiContact , "path" , path , "dii_type" , diiType )
1350+ .register (Metrics .globalRegistry ));
1351+ ds .record (count );
1352+ }
1353+ }
13221354
1323- DistributionSummary ds = _identityMapMetricSummaries .computeIfAbsent (apiContact , k -> DistributionSummary
1324- .builder ("uid2_operator_identity_map_inputs" )
1325- .description ("number of emails or email hashes passed to identity map batch endpoint" )
1326- .tags ("api_contact" , apiContact )
1327- .register (Metrics .globalRegistry ));
1328- ds .record (inputCount );
1329-
1330- Tuple .Tuple2 <Counter , Counter > ids = _identityMapUnmappedIdentifiers .computeIfAbsent (apiContact , k -> new Tuple .Tuple2 <>(
1355+ String cacheKey = apiContact + "|" + path ;
1356+ Tuple .Tuple2 <Counter , Counter > ids = _identityMapUnmappedIdentifiers .computeIfAbsent (cacheKey , k -> new Tuple .Tuple2 <>(
13311357 Counter .builder ("uid2_operator_identity_map_unmapped_total" )
13321358 .description ("invalid identifiers" )
1333- .tags ("api_contact" , apiContact , "reason" , "invalid" )
1359+ .tags ("api_contact" , apiContact , "reason" , "invalid" , "path" , path )
13341360 .register (Metrics .globalRegistry ),
13351361 Counter .builder ("uid2_operator_identity_map_unmapped_total" )
13361362 .description ("optout identifiers" )
1337- .tags ("api_contact" , apiContact , "reason" , "optout" )
1363+ .tags ("api_contact" , apiContact , "reason" , "optout" , "path" , path )
13381364 .register (Metrics .globalRegistry )));
13391365 if (invalidCount > 0 ) ids .getItem1 ().increment (invalidCount );
13401366 if (optoutCount > 0 ) ids .getItem2 ().increment (optoutCount );
13411367
1342- Counter rs = _identityMapRequestWithUnmapped .computeIfAbsent (apiContact , k -> Counter
1368+ Counter rs = _identityMapRequestWithUnmapped .computeIfAbsent (cacheKey , k -> Counter
13431369 .builder ("uid2_operator_identity_map_unmapped_requests_total" )
13441370 .description ("number of requests with unmapped identifiers" )
1345- .tags ("api_contact" , apiContact )
1371+ .tags ("api_contact" , apiContact , "path" , path )
13461372 .register (Metrics .globalRegistry ));
13471373 if (invalidCount > 0 || optoutCount > 0 ) {
13481374 rs .increment ();
13491375 }
1350- recordIdentityMapStatsForServiceLinks (rc , apiContact , inputCount , invalidCount , optoutCount );
1376+ recordIdentityMapStatsForServiceLinks (rc , apiContact , path , diiTypeCounts , invalidCount , optoutCount );
13511377 }
13521378
1353- private void recordIdentityMapStatsForServiceLinks (RoutingContext rc , String apiContact , int inputCount ,
1354- int invalidCount , int optOutCount ) {
1379+ private void recordIdentityMapStatsForServiceLinks (RoutingContext rc , String apiContact , String path ,
1380+ Map < String , Integer > diiTypeCounts , int invalidCount , int optOutCount ) {
13551381 // If request is from a service, break it down further by link_id
13561382 String serviceLinkName = rc .get (SecureLinkValidatorService .SERVICE_LINK_NAME , "" );
13571383 if (!serviceLinkName .isBlank ()) {
13581384 // serviceName will be non-empty as it will be inserted during validation
13591385 final String serviceName = rc .get (SecureLinkValidatorService .SERVICE_NAME );
1360- final String metricKey = serviceName + serviceLinkName ;
1361- DistributionSummary ds = _identityMapMetricSummaries .computeIfAbsent (metricKey ,
1362- k -> DistributionSummary .builder ("uid2_operator_identity_map_services_inputs" )
1363- .description ("number of emails or phone numbers passed to identity map batch endpoint by services" )
1364- .tags (Arrays .asList (Tag .of ("api_contact" , apiContact ),
1365- Tag .of ("service_name" , serviceName ),
1366- Tag .of ("service_link_name" , serviceLinkName )))
1367- .register (Metrics .globalRegistry ));
1368- ds .record (inputCount );
1369-
1370- Tuple .Tuple2 <Counter , Counter > counterTuple = _identityMapUnmappedIdentifiers .computeIfAbsent (metricKey ,
1386+
1387+ for (Map .Entry <String , Integer > entry : diiTypeCounts .entrySet ()) {
1388+ String diiType = entry .getKey ();
1389+ int count = entry .getValue ();
1390+ if (count > 0 ) {
1391+ final String cacheKey = serviceName + serviceLinkName + "|" + path + "|" + diiType ;
1392+ DistributionSummary ds = _identityMapServicesMetricSummaries .computeIfAbsent (cacheKey ,
1393+ k -> DistributionSummary .builder ("uid2_operator_identity_map_services_inputs" )
1394+ .description ("number of identifiers passed to identity map endpoint by services" )
1395+ .tags (Arrays .asList (Tag .of ("api_contact" , apiContact ),
1396+ Tag .of ("service_name" , serviceName ),
1397+ Tag .of ("service_link_name" , serviceLinkName ),
1398+ Tag .of ("path" , path ),
1399+ Tag .of ("dii_type" , diiType )))
1400+ .register (Metrics .globalRegistry ));
1401+ ds .record (count );
1402+ }
1403+ }
1404+
1405+ final String cacheKey = serviceName + serviceLinkName + "|" + path ;
1406+ Tuple .Tuple2 <Counter , Counter > counterTuple = _identityMapServicesUnmappedIdentifiers .computeIfAbsent (cacheKey ,
13711407 k -> new Tuple .Tuple2 <>(
13721408 Counter .builder ("uid2_operator_identity_map_services_unmapped_total" )
13731409 .description ("number of invalid identifiers passed to identity map batch endpoint by services" )
13741410 .tags (Arrays .asList (Tag .of ("api_contact" , apiContact ),
13751411 Tag .of ("reason" , "invalid" ),
13761412 Tag .of ("service_name" , serviceName ),
1377- Tag .of ("service_link_name" , serviceLinkName )))
1413+ Tag .of ("service_link_name" , serviceLinkName ),
1414+ Tag .of ("path" , path )))
13781415 .register (Metrics .globalRegistry ),
13791416 Counter .builder ("uid2_operator_identity_map_services_unmapped_total" )
13801417 .description ("number of optout identifiers passed to identity map batch endpoint by services" )
13811418 .tags (Arrays .asList (Tag .of ("api_contact" , apiContact ),
13821419 Tag .of ("reason" , "optout" ),
13831420 Tag .of ("service_name" , serviceName ),
1384- Tag .of ("service_link_name" , serviceLinkName )))
1421+ Tag .of ("service_link_name" , serviceLinkName ),
1422+ Tag .of ("path" , path )))
13851423 .register (Metrics .globalRegistry )));
13861424 if (invalidCount > 0 ) counterTuple .getItem1 ().increment (invalidCount );
13871425 if (optOutCount > 0 ) counterTuple .getItem2 ().increment (optOutCount );
@@ -1441,14 +1479,14 @@ private void handleOptoutStatus(RoutingContext rc) {
14411479
14421480 private void recordOptOutStatusEndpointStats (RoutingContext rc , int inputCount , int optOutCount ) {
14431481 String apiContact = getApiContact (rc );
1444- DistributionSummary inputDistSummary = optOutStatusCounters .computeIfAbsent (apiContact , k -> DistributionSummary
1482+ DistributionSummary inputDistSummary = optOutStatusInputSizeCounters .computeIfAbsent (apiContact , k -> DistributionSummary
14451483 .builder ("uid2_operator_optout_status_input_size" )
14461484 .description ("number of UIDs received in request" )
14471485 .tags ("api_contact" , apiContact )
14481486 .register (Metrics .globalRegistry ));
14491487 inputDistSummary .record (inputCount );
14501488
1451- DistributionSummary optOutDistSummary = optOutStatusCounters .computeIfAbsent (apiContact , k -> DistributionSummary
1489+ DistributionSummary optOutDistSummary = optOutStatusOptOutSizeCounters .computeIfAbsent (apiContact , k -> DistributionSummary
14521490 .builder ("uid2_operator_optout_status_optout_size" )
14531491 .description ("number of UIDs that have opted out" )
14541492 .tags ("api_contact" , apiContact )
0 commit comments