Date: 2026-03-09
Context: Oncall question about package targeting validation in Mission Control
Teams user asked whether child line items within a package must have matching targeting values when syncing from Operative One (O1) to Mission Control (MC), and if mismatched values (e.g., FireTV vs LGTV for device targeting) would cause a push error.
Yes — child line items within a package MUST have matching targeting values. If one child has FireTV and another has LGTV for MC_Device Name, the O1 → MC push will fail for those child line items.
The validation is enforced in order-manager during the O1 → MC sync pipeline, specifically in:
SalesOrderValidator.checkPackageTargets() (line 255)
- File:
order-manager/src/main/java/com/disney/digital/ads/order/manager/utils/validators/SalesOrderValidator.java
- Extracts all MC child line items from the package
- Converts each child's targeting to a JSON string (excluding exempted targets)
- Compares all children's targeting against the first child using
JSONAssert.assertEquals()withLENIENTmode - If ANY child has different targeting → validation fails
"- child line item targets must match all other targets in same package"
Result: Failed child line items get status FAIL and are NOT synced to MC. Valid line items in the same package can still sync (partial success is allowed).
Two targeting dimensions are excluded from the matching check (child lines CAN have different values for these):
Spot Length— different child lines can have different spot lengthsMC_Publisher— different child lines can have different publishers
This is implemented in SalesOrderParsingHelper.getFilteredTargetListInJsonString():
.read("$.targets.targets[?(@!=null && @.name!='Spot Length' && @.name!='MC_Publisher')]")All other MC targets (including MC_Device Name) MUST match across child lines.
Certain product content types skip the targeting validation entirely:
Order-level skip (skips all package validations):
DSE,DXP
Product-level skip (individual child lines are excluded from the comparison):
DSE,DXP,Sports,Hulu,Deportes
Config: order-manager/config/application.properties (lines 116-117)
order.line.item.skip.validation.product.content.types=DSE,DXP
order.product.content.types.skip.targets.validation=DSE,DXP,Sports,Hulu,DeportesIn addition to targeting, order-manager validates that package children must match on:
- Start/end dates — must match the parent package dates
- Billable 3rd party servers — must match if package is Demo Guaranteed (Nielsen DTA)
- DAS O1 Line Item IDs — no duplicates within the same package
Campaign-manager does NOT enforce package-level targeting consistency. It validates individual line items independently. The package targeting matching is purely an order-manager sync-time validation.
Q: Do child lines within a package need matching targeting values?
A: Yes. All MC child line items in a package must have identical targeting, with two exceptions:Spot LengthandMC_Publishercan differ.
Q: If one child has FireTV and another has LGTV in MC_Device Name, will it cause a push error?
A: Yes. This will cause a push error with message: "child line item targets must match all other targets in same package". The mismatched child line items will fail to sync.
Q: Are any MC targets excluded from this?
A: Yes —Spot LengthandMC_Publisherare excluded. Additionally, child lines with Product Content Type ofDSE,DXP,Sports,Hulu, orDeportesare exempt from the check entirely.
Expected Behavior — this is a deliberate validation rule in order-manager.
File: order-manager/src/main/java/com/disney/digital/ads/order/manager/utils/validators/SalesOrderValidator.java
/**
* All MC line items within the same package should have the same targets list
* @param salesOrderLineItem the package that contains a pushed line item
* @return true if passed check
*/
private boolean checkPackageTargets(JsonNode salesOrderLineItem, Map<String, Set<String>> lineItemsIdsToProductContentTypes) {
List<String> lineItemsTargetsStringList =
StreamSupport.stream(salesOrderParsingHelper.extractChildLineItemsListFromPackage(salesOrderLineItem).spliterator(), false)
.filter(childNode -> salesOrderParsingHelper.isMissionControlLine(childNode)
&& !skipCheckPackageTargets(childNode, lineItemsIdsToProductContentTypes))
.map(filteredChildNode -> salesOrderParsingHelper.getFilteredTargetListInJsonString(filteredChildNode))
.toList();
if (CollectionUtils.isEmpty(lineItemsTargetsStringList)) {
return true;
}
try {
String expectedTargets = lineItemsTargetsStringList.get(0);
lineItemsTargetsStringList.forEach(targetsstring ->
JSONAssert.assertEquals(expectedTargets, targetsstring, JSONCompareMode.LENIENT));
return true;
} catch (AssertionError e) {
logger.error("Packaged line item targets do not match: {}", e.getMessage());
return false;
}
}
private boolean skipCheckPackageTargets(JsonNode childLineItem, Map<String, Set<String>> lineItemsIdsToSkipValidation) {
String id = salesOrderParsingHelper.getIdFromNode(childLineItem);
Set<String> productContentTypes = lineItemsIdsToSkipValidation.getOrDefault(id, Set.of());
return productContentTypes.stream().anyMatch(type ->
productContentTypesSkipTargetsValidation.stream().anyMatch(skipType -> skipType.equalsIgnoreCase(type)));
}File: order-manager/src/main/java/com/disney/digital/ads/order/manager/utils/SalesOrderParsingHelper.java
public String getFilteredTargetListInJsonString(JsonNode lineItem) {
try {
List<Map<String, Object>> filteredTargets = JsonPath
.read(lineItem.toString(), "$.targets.targets[?(@!=null && @.name!='Spot Length' && @.name!='MC_Publisher')]");
return new ObjectMapper().writeValueAsString(filteredTargets);
} catch (Exception e) {
logger.error("Failed to get filtered targets from line item: {}", e.getMessage());
return "";
}
}-
ODSM-192 - Update Parent and Child Line Item Logic
https://confluence.disney.com/x/mSK8YQ
Confirms: "Packages are not serveable and targeting is not applied on it" (parent package level) -
Hulu O1: Mission Control Package Creation Template
https://confluence.disney.com/x/QLd7Xg
Template for creating packages in Mission Control
-
Package Structure:
- Parent line item (package): Not serveable, no targeting applied
- Child line items: Serveable, must have matching targeting (with exceptions)
- Standalone/Packageless line items: No package parent, validated independently
-
CQRS Pattern:
- order-manager: O1 → MC sync pipeline (where validation occurs)
- campaign-manager: Write side (receives validated data)
- campaign-searcher: Read side (Elasticsearch)
File: order-manager/src/test/java/com/disney/digital/ads/order/manager/utils/validators/SalesOrderValidatorTest.java
Tests verify:
- Matching targeting validation (lines 302, 377)
- Product content type exemptions
- Target exclusions (Spot Length, MC_Publisher)
- Partial sync success (valid lines sync, invalid lines fail)