From fad7334d98ca906680fbd60d0ebdeb9838e11392 Mon Sep 17 00:00:00 2001 From: infytvcode <104983807+infytvcode@users.noreply.github.com> Date: Tue, 10 May 2022 18:17:49 +0530 Subject: [PATCH 1/2] - Added infytv connector --- Dockerfile | 2 +- sample/prebid-config.yaml | 13 +- .../server/bidder/infytv/InfytvBidder.java | 118 ++++++++++++++++++ .../ext/request/infytv/ExtImpInfytv.java | 36 ++++++ .../config/bidder/InfytvConfiguration.java | 54 ++++++++ src/main/resources/bidder-config/infytv.yaml | 114 +++++++++++++++++ .../static/bidder-params/infytv.json | 17 +++ 7 files changed, 350 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java create mode 100644 src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java create mode 100644 src/main/resources/bidder-config/infytv.yaml create mode 100644 src/main/resources/static/bidder-params/infytv.json diff --git a/Dockerfile b/Dockerfile index cbd9db98f79..6d052beb54a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:11-jre-slim +FROM openjdk:17-jre-slim WORKDIR /app/prebid-server diff --git a/sample/prebid-config.yaml b/sample/prebid-config.yaml index fbfb0badbf4..c1b1bfb5d03 100644 --- a/sample/prebid-config.yaml +++ b/sample/prebid-config.yaml @@ -1,11 +1,13 @@ status-response: "ok" adapters: - rubicon: + infytv: enabled: true - XAPI.Username: user1 - XAPI.Password: password1 + modifying-vast-xml-allowed: true metrics: prefix: prebid + console: + enabled: false + interval: 300 cache: scheme: http host: localhost @@ -23,3 +25,8 @@ gdpr: vendorlist: v2: cache-dir: /var/tmp/vendor2 +analytics: + log: + enabled: true +auction: + default-timeout-ms: 1600 diff --git a/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java b/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java new file mode 100644 index 00000000000..b0d78eaf63a --- /dev/null +++ b/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java @@ -0,0 +1,118 @@ +package org.prebid.server.bidder.infytv; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.iab.openrtb.request.BidRequest; +import com.iab.openrtb.request.Imp; +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.ExtPrebid; +import org.prebid.server.proto.openrtb.ext.request.appnexus.ExtImpAppnexus; +import org.prebid.server.proto.openrtb.ext.request.infytv.ExtImpInfytv; +import org.prebid.server.proto.openrtb.ext.response.BidType; +import org.prebid.server.util.HttpUtil; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class InfytvBidder implements Bidder{ + final String endpointUrl; + private final JacksonMapper mapper; + + private static final TypeReference> INFYTV_EXT_TYPE_REFERENCE = + new TypeReference<>() { + }; + + public InfytvBidder(String endpointUrl, JacksonMapper mapper) { + this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); + this.mapper = Objects.requireNonNull(mapper); + } + + @Override + public Result>> makeHttpRequests(BidRequest request) { + final List> httpRequests = new ArrayList<>(); + for (Imp imp : request.getImp()) { + ExtImpInfytv infyVars = ResolveImpExt(imp); + final BidRequest outgoingRequest = request.toBuilder().imp(Collections.singletonList(imp)).build(); + final String dspUrl = infyVars.getBase()+infyVars.getPath(); + httpRequests.add(HttpRequest.builder() + .method(HttpMethod.POST) + .uri(dspUrl) + .headers(HttpUtil.headers()) + .payload(outgoingRequest) + .body(mapper.encodeToBytes(outgoingRequest)) + .build()); + } + + return Result.withValues(httpRequests); + } + + @Override + public final Result> makeBids(HttpCall httpCall, BidRequest bidRequest) { + try { + final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); + return Result.withValues(extractBids(httpCall.getRequest().getPayload(), bidResponse)); + } catch (DecodeException | PreBidException e) { + return Result.withError(BidderError.badServerResponse(e.getMessage())); + } + } + + private static List extractBids(BidRequest bidRequest, BidResponse bidResponse) { + if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { + return Collections.emptyList(); + } + return bidsFromResponse(bidRequest, bidResponse); + } + + private static List bidsFromResponse(BidRequest bidRequest, BidResponse bidResponse) { + return bidResponse.getSeatbid().stream() + .filter(Objects::nonNull) + .map(SeatBid::getBid) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .map(bid -> BidderBid.of(bid, getBidType(bid.getImpid(), bidRequest.getImp()), bidResponse.getCur())) + .collect(Collectors.toList()); + } + + private static BidType getBidType(String impId, List imps) { + BidType bidType = BidType.banner; + for (Imp imp : imps) { + if (imp.getId().equals(impId)) { + if (imp.getBanner() != null) { + return bidType; + } else if (imp.getVideo() != null) { + bidType = BidType.video; + } else if (imp.getXNative() != null) { + bidType = BidType.xNative; + } else if (imp.getAudio() != null) { + bidType = BidType.audio; + } + } + } + return bidType; + } + + private ExtImpInfytv ResolveImpExt(Imp imp) { + try { + return mapper.mapper() + .convertValue(imp.getExt(), INFYTV_EXT_TYPE_REFERENCE) + .getBidder(); + } catch (IllegalArgumentException e) { + throw new PreBidException(e.getMessage(), e); + } + } +} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java new file mode 100644 index 00000000000..e1b6bf6f9ae --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java @@ -0,0 +1,36 @@ +package org.prebid.server.proto.openrtb.ext.request.infytv; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Value; + +/** + * Defines the contract for bidrequest.imp[i].ext.{bidder} + */ +@AllArgsConstructor(staticName = "of") +@Value +public class ExtImpInfytv { + @JsonProperty("dsp_id") + Integer dspId; + + @JsonProperty("customer_id") + Integer customerId; + + @JsonProperty("tag_id") + Integer tagId; + + @JsonProperty("base") + String base; + + @JsonProperty("path") + String path; + + @JsonProperty("dsp_type") + String dspType; + + @JsonProperty("min_cpm") + Double minCpm; + + @JsonProperty("max_cpm") + Double maxCpm; +} diff --git a/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java new file mode 100644 index 00000000000..be97b1aa786 --- /dev/null +++ b/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java @@ -0,0 +1,54 @@ +package org.prebid.server.spring.config.bidder; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.prebid.server.bidder.BidderDeps; +import org.prebid.server.bidder.infytv.InfytvBidder; +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.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; +import java.util.Map; + +@Configuration +@PropertySource(value = "classpath:/bidder-config/infytv.yaml", factory = YamlPropertySourceFactory.class) +public class InfytvConfiguration { + private static final String BIDDER_NAME = "infytv"; + + @Bean("infytvConfigurationProperties") + @ConfigurationProperties("adapters.infytv") + BidderConfigurationProperties configurationProperties() { + return new BidderConfigurationProperties(); + } + + @Bean + BidderDeps infytvBidderDeps(BidderConfigurationProperties infytvConfigurationProperties, + @NotBlank @Value("${external-url}") String externalUrl, + JacksonMapper mapper) { + + return BidderDepsAssembler.forBidder(BIDDER_NAME) + .withConfig(infytvConfigurationProperties) + .usersyncerCreator(UsersyncerCreator.create(externalUrl)) + .bidderCreator(config -> new InfytvBidder(config.getEndpoint(), mapper)) + .assemble(); + } + + @Data + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + private static class InfytvConfigurationProperties extends BidderConfigurationProperties { + + Integer platformId; + + Map iabCategories; + } +} diff --git a/src/main/resources/bidder-config/infytv.yaml b/src/main/resources/bidder-config/infytv.yaml new file mode 100644 index 00000000000..b53875db92a --- /dev/null +++ b/src/main/resources/bidder-config/infytv.yaml @@ -0,0 +1,114 @@ +adapters: + infytv: + endpoint: http://nxs.infy.tv/openrtb2/infytv + meta-info: + maintainer-email: tech+prebid@infy.tv + app-media-types: + - video + site-media-types: + - video + supported-vendors: + vendor-id: 0 + usersync: + url: https://ib.adnxs.com/getuid? + redirect-url: /setuid?bidder=adnxs&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&uid=$UID + cookie-family-name: infytv + type: redirect + support-cors: false + platform-id: 5 + iab-categories: + 1: IAB20-3 + 2: IAB18-5 + 3: IAB10-1 + 4: IAB2-3 + 5: IAB19-8 + 6: IAB22-1 + 7: IAB18-1 + 8: IAB12-3 + 9: IAB5-1 + 10: IAB4-5 + 11: IAB13-4 + 12: IAB8-7 + 13: IAB9-7 + 14: IAB7-1 + 15: IAB20-18 + 16: IAB10-7 + 17: IAB19-18 + 18: IAB13-6 + 19: IAB18-4 + 20: IAB1-5 + 21: IAB1-6 + 22: IAB3-4 + 23: IAB19-13 + 24: IAB22-2 + 25: IAB3-9 + 26: IAB17-18 + 27: IAB19-6 + 28: IAB1-7 + 29: IAB9-30 + 30: IAB20-7 + 31: IAB20-17 + 32: IAB7-32 + 33: IAB16-5 + 34: IAB19-34 + 35: IAB11-5 + 36: IAB12-3 + 37: IAB11-4 + 38: IAB12-3 + 39: IAB9-30 + 41: IAB7-44 + 42: IAB7-1 + 43: IAB7-30 + 50: IAB19-30 + 51: IAB17-12 + 52: IAB19-30 + 53: IAB3-1 + 55: IAB13-2 + 56: IAB19-30 + 57: IAB19-30 + 58: IAB7-39 + 59: IAB22-1 + 60: IAB7-39 + 61: IAB21-3 + 62: IAB5-1 + 63: IAB12-3 + 64: IAB20-18 + 65: IAB11-2 + 66: IAB17-18 + 67: IAB9-9 + 68: IAB9-5 + 69: IAB7-44 + 71: IAB22-3 + 73: IAB19-30 + 74: IAB8-5 + 78: IAB22-1 + 85: IAB12-2 + 86: IAB22-3 + 87: IAB11-3 + 112: IAB7-32 + 113: IAB7-32 + 114: IAB7-32 + 115: IAB7-32 + 118: IAB9-5 + 119: IAB9-5 + 120: IAB9-5 + 121: IAB9-5 + 122: IAB9-5 + 123: IAB9-5 + 124: IAB9-5 + 125: IAB9-5 + 126: IAB9-5 + 127: IAB22-1 + 132: IAB1-2 + 133: IAB19-30 + 137: IAB3-9 + 138: IAB19-3 + 140: IAB2-3 + 141: IAB2-1 + 142: IAB2-3 + 143: IAB17-13 + 166: IAB11-4 + 175: IAB3-1 + 176: IAB13-4 + 182: IAB8-9 + 183: IAB3-5 diff --git a/src/main/resources/static/bidder-params/infytv.json b/src/main/resources/static/bidder-params/infytv.json new file mode 100644 index 00000000000..9f2702ea0e9 --- /dev/null +++ b/src/main/resources/static/bidder-params/infytv.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "InfyTV Adapter Params", + "description": "A schema which validates params accepted by the InfyTV adapter", + "type": "object", + "properties": { + "dsp_id": { + "type": "string", + "description": "dsp_id" + }, + "customer_id": { + "type": "string", + "description": "customer_id" + } + }, + "required": ["dsp_id", "customer_id"] +} From 1e5b7cffb3a09a24e551e50576282d4b92086cfe Mon Sep 17 00:00:00 2001 From: infytvcode <104983807+infytvcode@users.noreply.github.com> Date: Wed, 11 May 2022 16:51:28 +0530 Subject: [PATCH 2/2] - Updating for docker deployment --- Dockerfile | 3 +- README.md | 23 +++++++++++++++ src/main/docker/app-settings.yaml | 2 ++ src/main/docker/application.yaml | 28 +++++++++++++++++++ .../server/bidder/infytv/InfytvBidder.java | 10 +++---- .../ext/request/infytv/ExtImpInfytv.java | 1 + .../config/bidder/InfytvConfiguration.java | 5 ++-- 7 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 src/main/docker/app-settings.yaml diff --git a/Dockerfile b/Dockerfile index 6d052beb54a..c5db7326dd4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:17-jre-slim +FROM openjdk:17.0.2-oracle WORKDIR /app/prebid-server @@ -7,6 +7,7 @@ VOLUME /app/prebid-server/data COPY src/main/docker/run.sh ./ COPY src/main/docker/application.yaml ./ +COPY src/main/docker/app-settings.yaml ./ COPY target/prebid-server.jar ./ EXPOSE 8080 diff --git a/README.md b/README.md index 617fbe46527..fde71190442 100644 --- a/README.md +++ b/README.md @@ -117,3 +117,26 @@ and verify response status is `200 OK`. - [Code Style](docs/developers/code-style.md) - [Code Review](docs/developers/code-reviews.md) - [Versioning](docs/developers/versioning.md) + + +## Docker build + +- To build run +```bash +docker build -t infytv/infy:hb-latest . +``` + +- To push on docker hub run +```bash +docker push infytv/infy:hb-latest +``` +- To pull from docker hub run +```bash +docker pull infytv/infy:hb-latest +``` + +- To run +```bash +docker run -d -p 8080:8080 \ + infytv/infy:hb-latest +``` diff --git a/src/main/docker/app-settings.yaml b/src/main/docker/app-settings.yaml new file mode 100644 index 00000000000..5b3303a663c --- /dev/null +++ b/src/main/docker/app-settings.yaml @@ -0,0 +1,2 @@ +accounts: + - id: 1001 diff --git a/src/main/docker/application.yaml b/src/main/docker/application.yaml index 458f9b4d25e..c0fc6bf5fa6 100644 --- a/src/main/docker/application.yaml +++ b/src/main/docker/application.yaml @@ -1,4 +1,32 @@ +status-response: "ok" +adapters: + infytv: + enabled: true + modifying-vast-xml-allowed: true +metrics: + prefix: prebid + console: + enabled: false + interval: 300 +cache: + scheme: http + host: localhost + path: /cache + query: uuid= +settings: + filesystem: + settings-filename: app-settings.yaml + stored-requests-dir: + stored-imps-dir: + stored-responses-dir: + categories-dir: gdpr: + default-value: 1 vendorlist: v2: cache-dir: /app/prebid-server/data/vendorlist-v2 +analytics: + log: + enabled: true +auction: + default-timeout-ms: 1600 diff --git a/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java b/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java index b0d78eaf63a..2a1c6f80aa1 100644 --- a/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java +++ b/src/main/java/org/prebid/server/bidder/infytv/InfytvBidder.java @@ -17,7 +17,6 @@ import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.ExtPrebid; -import org.prebid.server.proto.openrtb.ext.request.appnexus.ExtImpAppnexus; import org.prebid.server.proto.openrtb.ext.request.infytv.ExtImpInfytv; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.util.HttpUtil; @@ -29,7 +28,8 @@ import java.util.Objects; import java.util.stream.Collectors; -public class InfytvBidder implements Bidder{ +public class InfytvBidder implements Bidder { + final String endpointUrl; private final JacksonMapper mapper; @@ -46,9 +46,9 @@ public InfytvBidder(String endpointUrl, JacksonMapper mapper) { public Result>> makeHttpRequests(BidRequest request) { final List> httpRequests = new ArrayList<>(); for (Imp imp : request.getImp()) { - ExtImpInfytv infyVars = ResolveImpExt(imp); + ExtImpInfytv infyVars = resolveImpExt(imp); final BidRequest outgoingRequest = request.toBuilder().imp(Collections.singletonList(imp)).build(); - final String dspUrl = infyVars.getBase()+infyVars.getPath(); + final String dspUrl = infyVars.getBase() + infyVars.getPath(); httpRequests.add(HttpRequest.builder() .method(HttpMethod.POST) .uri(dspUrl) @@ -106,7 +106,7 @@ private static BidType getBidType(String impId, List imps) { return bidType; } - private ExtImpInfytv ResolveImpExt(Imp imp) { + private ExtImpInfytv resolveImpExt(Imp imp) { try { return mapper.mapper() .convertValue(imp.getExt(), INFYTV_EXT_TYPE_REFERENCE) diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java index e1b6bf6f9ae..3b3f685aae2 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/infytv/ExtImpInfytv.java @@ -10,6 +10,7 @@ @AllArgsConstructor(staticName = "of") @Value public class ExtImpInfytv { + @JsonProperty("dsp_id") Integer dspId; diff --git a/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java index be97b1aa786..fc791ec8884 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/InfytvConfiguration.java @@ -22,6 +22,7 @@ @Configuration @PropertySource(value = "classpath:/bidder-config/infytv.yaml", factory = YamlPropertySourceFactory.class) public class InfytvConfiguration { + private static final String BIDDER_NAME = "infytv"; @Bean("infytvConfigurationProperties") @@ -32,8 +33,8 @@ BidderConfigurationProperties configurationProperties() { @Bean BidderDeps infytvBidderDeps(BidderConfigurationProperties infytvConfigurationProperties, - @NotBlank @Value("${external-url}") String externalUrl, - JacksonMapper mapper) { + @NotBlank @Value("${external-url}") String externalUrl, + JacksonMapper mapper) { return BidderDepsAssembler.forBidder(BIDDER_NAME) .withConfig(infytvConfigurationProperties)