Skip to content

Conversation

@tomaszbmf
Copy link
Contributor

@tomaszbmf tomaszbmf commented Apr 16, 2025

This PR removes the tagid_src parameter, which was previously used to signal that the publisher is providing their own ID instead of using ours, and the pub_id query parameter, which was only necessary when tagid_src was present. After confirming that publishers do not utilize these parameters, we determined both are unnecessary. Removing them will simplify the setup and reduce confusion for our users.

🔧 Type of changes

  • bid adapter update
  • configuration

✨ What's the context?

tagid_src is effectively not used, pub_id is only necessary when tagid_src is present

🧠 Rationale behind the change

Removing it will help simplify the setup and reduce confusion for our users.

🧪 Test plan

we don't see requests with tagid_src query param

🏎 Quality check

@tomaszbmf tomaszbmf changed the title MobileFuse Adapter: Remove tagid_src to Simplify Partner ID Setup MobileFuse Adapter: Remove tagid_src and pub_id for Simplified Partner ID Setup Apr 22, 2025
@tomaszbmf tomaszbmf marked this pull request as ready for review April 22, 2025 15:52
@tomaszbmf tomaszbmf changed the title MobileFuse Adapter: Remove tagid_src and pub_id for Simplified Partner ID Setup MobileFuse Adapter: Remove tagid_src and pub_id params Apr 22, 2025
@osulzhenko osulzhenko requested a review from CTMBNara April 28, 2025 07:57
private String makeUrl(ExtImpMobilefuse extImp) {
final String baseUrl = endpointUrl + Objects.toString(extImp.getPublisherId(), "0");
return "ext".equals(extImp.getTagidSrc()) ? baseUrl + "&tagid_src=ext" : baseUrl;
return endpointUrl;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like you don't the following part of code as well

        final String endpoint = request.getImp().stream()
                .map(this::parseImpExt)
                .filter(Objects::nonNull)
                .findFirst()
                .map(this::makeUrl)
                .orElse(null);

please clean up redundant code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out! I've removed the redundant code as suggested.

To ensure stability after removing the .map(this::parseImpExt).filter(Objects::nonNull) chain, I added a null check in the modifyImp(Imp imp) method. This prevents a potential NullPointerException in cases where parseImpExt could return null.

Let me know if there's anything else you'd like me to update!

AntoxaAntoxic
AntoxaAntoxic previously approved these changes May 13, 2025
Comment on lines 67 to 69
if (impExt == null) {
return null;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this. If there is no impExt then imp will be filtered out for that bidder

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I see that in GO they fail on invalid impExt instead of ignoring errors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've removed the check as suggested.

@CTMBNara
Copy link
Collaborator

@tomaszbmf Please, change the logic so that the adapter fails on invalid imp.ext, like in GO, instead of ignoring errors

#3915 (comment)

@tomaszbmf
Copy link
Contributor Author

@tomaszbmf Please, change the logic so that the adapter fails on invalid imp.ext, like in GO, instead of ignoring errors

#3915 (comment)

I've updated the code to reintroduce the "Invalid ExtImpMobilefuse value" error when no valid ext is present in any of the request imp objects.

Previously, the presence of ext was checked indirectly as part of building the endpoint from ext values. Since the endpoint is no longer constructed based on those values, I had initially removed that logic. However, based on feedback, I’ve added back the validation in a simplified form:

final boolean hasExt = request.getImp().stream()
    .map(this::parseImpExt)
    .anyMatch(Objects::nonNull);

if (!hasExt) {
    return Result.withError(BidderError.badInput("Invalid ExtImpMobilefuse value"));
}

Reintroduces the "Invalid ExtImpMobilefuse value" error when no imp in the request contains a valid ext object. This preserves the original validation logic that was previously removed when the endpoint construction stopped relying on ext.

This change retains the updated endpoint handling logic and does not require any unit test modifications compared to the main branch.

Copy link
Collaborator

@CTMBNara CTMBNara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, the updated code still doesn't comply with GO logic: you need to collect all errors until valid ext

	mobileFuseExtension, errs := getFirstMobileFuseExtension(bidRequest)
	if errs != nil {
		return nil, errs
	}
		err := jsonutil.Unmarshal(imp.Ext, &bidder_imp_extension)

		if err != nil {
			errs = append(errs, err)
			continue
		}

		err = jsonutil.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension)

		if err != nil {
			errs = append(errs, err)
			continue
		}

Also, to simplify the adapter code and bring it closer to the GO logic, I suggest changing it a little as follows:

    @Override
    public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request) {
        final List<Imp> modifiedImps = new ArrayList<>();
        final List<BidderError> errors = new ArrayList<>();

        for (Imp imp : request.getImp()) {
            try {
                if (!isValidImp(imp)) {
                    continue;
                }

                final ExtImpMobilefuse extImp = parseImpExt(imp);
                modifiedImps.add(modifyImp(imp, extImp));
            } catch (PreBidException e) {
                errors.add(BidderError.badInput(e.getMessage()));
            }
        }

        if (!errors.isEmpty()) {
            return Result.withErrors(errors);
        }

        final BidRequest modifiedRequest = request.toBuilder().imp(modifiedImps).build();
        return Result.withValue(BidderUtil.defaultRequest(modifiedRequest, endpointUrl, mapper));
    }

    private static boolean isValidImp(Imp imp) {
        return imp.getBanner() != null || imp.getVideo() != null || imp.getXNative() != null;
    }

    private ExtImpMobilefuse parseImpExt(Imp imp) {
        try {
            return mapper.mapper().convertValue(imp.getExt(), MOBILEFUSE_EXT_TYPE_REFERENCE).getBidder();
        } catch (IllegalArgumentException e) {
            throw new PreBidException(e.getMessage());
        }
    }

    private Imp modifyImp(Imp imp, ExtImpMobilefuse extImp) {
        final ObjectNode skadn = parseSkadn(imp.getExt());
        return imp.toBuilder()
                .tagid(Objects.toString(extImp.getPlacementId(), "0"))
                .ext(skadn != null ? mapper.mapper().createObjectNode().set(SKADN_PROPERTY_NAME, skadn) : null)
                .build();
    }

    private ObjectNode parseSkadn(ObjectNode impExt) {
        try {
            return mapper.mapper().convertValue(impExt.get(SKADN_PROPERTY_NAME), ObjectNode.class);
        } catch (IllegalArgumentException e) {
            throw new PreBidException(e.getMessage());
        }
    }

@tomaszbmf
Copy link
Contributor Author

Thanks for the clarification and the code suggestion! 🙏

I’ve now pushed the updated changes incorporating your snippet (with a minor adjustment). Initially, I was aiming to keep the scope minimal and focused strictly on the original change, so I didn’t fully catch the broader alignment you were aiming for with the Golang version. Appreciate your patience, and let me know if anything else needs tweaking!

@osulzhenko osulzhenko requested a review from CTMBNara June 2, 2025 10:24
}

private ObjectNode parseSkadn(ObjectNode impExt) {
private ObjectNode parseSkadn(ObjectNode impExt) throws PreBidException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for throws

}

private ExtImpMobilefuse parseImpExt(Imp imp) {
private ExtImpMobilefuse parseImpExt(Imp imp) throws PreBidException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorder the methods so that they are placed in the order they are called

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applied both changes

@tomaszbmf tomaszbmf requested a review from CTMBNara June 5, 2025 13:09
@osulzhenko osulzhenko linked an issue Jun 10, 2025 that may be closed by this pull request
@tomaszbmf
Copy link
Contributor Author

@AntoxaAntoxic @CTMBNara Just following up on the requested changes. Let me know if anything else is needed to move forward with merging.

@CTMBNara CTMBNara merged commit 1822c12 into prebid:master Jul 1, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port PR from PBS-Go: MobileFuse: Remove tagid_src and pub_id params

4 participants