Skip to content

Commit

Permalink
Add SaLunamedia bidder (#1364)
Browse files Browse the repository at this point in the history
  • Loading branch information
And1sS authored and nickluck8 committed Aug 10, 2021
1 parent 30aae38 commit f794659
Show file tree
Hide file tree
Showing 11 changed files with 659 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.prebid.server.bidder.salunamedia;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.response.Bid;
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
import io.vertx.core.http.HttpMethod;
import org.apache.commons.collections4.CollectionUtils;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderError;
import org.prebid.server.bidder.model.HttpCall;
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.proto.openrtb.ext.response.BidType;
import org.prebid.server.util.HttpUtil;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
* SaLunamedia {@link Bidder} implementation
*/
public class SaLunamediaBidder implements Bidder<BidRequest> {

private final String endpointUrl;
private final JacksonMapper mapper;

public SaLunamediaBidder(String endpointUrl, JacksonMapper mapper) {
this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl));
this.mapper = Objects.requireNonNull(mapper);
}

@Override
public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request) {
return Result.withValue(HttpRequest.<BidRequest>builder()
.uri(endpointUrl)
.method(HttpMethod.POST)
.headers(HttpUtil.headers())
.payload(request)
.body(mapper.encode(request))
.build());
}

@Override
public Result<List<BidderBid>> makeBids(HttpCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
return Result.of(extractBids(bidResponse), Collections.emptyList());
} catch (DecodeException | PreBidException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
}
}

private List<BidderBid> extractBids(BidResponse bidResponse) {
final List<SeatBid> seatBids = bidResponse != null ? bidResponse.getSeatbid() : null;
if (CollectionUtils.isEmpty(seatBids)) {
throw new PreBidException("Empty SeatBid");
}

final SeatBid firstSeatBid = seatBids.get(0);
final List<Bid> bids = firstSeatBid != null ? firstSeatBid.getBid() : null;
if (CollectionUtils.isEmpty(bids)) {
throw new PreBidException("Empty SeatBid.Bids");
}

final Bid firstBid = bids.get(0);
final ObjectNode firstBidExt = firstBid != null ? firstBid.getExt() : null;
if (firstBidExt == null) {
throw new PreBidException("Missing BidExt");
}

return Collections.singletonList(BidderBid.of(firstBid, getBidType(firstBidExt), bidResponse.getCur()));
}

private BidType getBidType(ObjectNode bidExt) {
try {
return mapper.mapper().convertValue(bidExt.get("mediaType"), BidType.class);
} catch (IllegalArgumentException e) {
throw new PreBidException(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.prebid.server.spring.config.bidder;

import org.prebid.server.bidder.BidderDeps;
import org.prebid.server.bidder.salunamedia.SaLunamediaBidder;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties;
import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler;
import org.prebid.server.spring.config.bidder.util.UsersyncerCreator;
import org.prebid.server.spring.env.YamlPropertySourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.validation.constraints.NotBlank;

@Configuration
@PropertySource(value = "classpath:/bidder-config/salunamedia.yaml", factory = YamlPropertySourceFactory.class)
public class SaLunamediaConfiguration {

private static final String BIDDER_NAME = "sa_lunamedia";

@Value("${external-url}")
@NotBlank
private String externalUrl;

@Autowired
private JacksonMapper mapper;

@Autowired
@Qualifier("salunamediaConfigurationProperties")
private BidderConfigurationProperties configProperties;

@Bean("salunamediaConfigurationProperties")
@ConfigurationProperties("adapters.salunamedia")
BidderConfigurationProperties configurationProperties() {
return new BidderConfigurationProperties();
}

@Bean
BidderDeps saLunamediaBidderDeps() {
return BidderDepsAssembler.forBidder(BIDDER_NAME)
.withConfig(configProperties)
.usersyncerCreator(UsersyncerCreator.create(externalUrl))
.bidderCreator(config -> new SaLunamediaBidder(config.getEndpoint(), mapper))
.assemble();
}
}
27 changes: 27 additions & 0 deletions src/main/resources/bidder-config/salunamedia.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
adapters:
sa_lunamedia:
enabled: false
endpoint: https://mobile.mng-ads.com/bidrequest{{ZoneID}}
pbs-enforces-gdpr: true
pbs-enforces-ccpa: true
modifying-vast-xml-allowed: true
deprecated-names:
aliases: {}
meta-info:
maintainer-email: support@lunamedia.io
app-media-types:
- banner
- video
- native
site-media-types:
- banner
- video
- native
supported-vendors:
vendor-id: 998
usersync:
url: https://cookie.lmgssp.com/pserver?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&ccpa={{us_privacy}}&redirect=
redirect-url: /setuid?bidder=sa_lunamedia&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&uid=[UID]
cookie-family-name: sa_lunamedia
type: redirect
support-cors: false
17 changes: 17 additions & 0 deletions src/main/resources/static/bidder-params/sa_lunamedia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Sa_Lunamedia Adapter Params",
"description": "A schema which validates params accepted by the Sa_Lunamedia adapter",
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "network or placement key"
},
"type": {
"type": "string",
"enum": ["network", "publisher"]
}
},
"required": ["key"]
}
Loading

0 comments on commit f794659

Please sign in to comment.