1212import org .prebid .server .execution .timeout .Timeout ;
1313import org .prebid .server .json .DecodeException ;
1414import org .prebid .server .json .JacksonMapper ;
15+ import org .prebid .server .settings .helper .StoredItemResolver ;
1516import org .prebid .server .settings .model .Account ;
1617import org .prebid .server .settings .model .Category ;
1718import org .prebid .server .settings .model .Profile ;
1819import org .prebid .server .settings .model .SettingsFile ;
1920import org .prebid .server .settings .model .StoredDataResult ;
2021import org .prebid .server .settings .model .StoredDataType ;
22+ import org .prebid .server .settings .model .StoredItem ;
2123import org .prebid .server .settings .model .StoredResponseDataResult ;
2224
2325import java .io .File ;
2426import java .io .IOException ;
27+ import java .util .ArrayList ;
2528import java .util .Collections ;
29+ import java .util .HashMap ;
2630import java .util .List ;
2731import java .util .Map ;
2832import java .util .Objects ;
@@ -49,13 +53,15 @@ public class FileApplicationSettings implements ApplicationSettings {
4953 private final Map <String , Account > accounts ;
5054 private final Map <String , String > storedIdToRequest ;
5155 private final Map <String , String > storedIdToImp ;
56+ private final Map <String , Set <StoredItem <Profile >>> profileIdToProfile ;
5257 private final Map <String , String > storedIdToSeatBid ;
5358 private final Map <String , Map <String , Category >> fileToCategories ;
5459
5560 public FileApplicationSettings (FileSystem fileSystem ,
5661 String settingsFileName ,
5762 String storedRequestsDir ,
5863 String storedImpsDir ,
64+ String profilesDir ,
5965 String storedResponsesDir ,
6066 String categoriesDir ,
6167 JacksonMapper jacksonMapper ) {
@@ -71,6 +77,7 @@ public FileApplicationSettings(FileSystem fileSystem,
7177
7278 storedIdToRequest = readStoredData (fileSystem , Objects .requireNonNull (storedRequestsDir ));
7379 storedIdToImp = readStoredData (fileSystem , Objects .requireNonNull (storedImpsDir ));
80+ profileIdToProfile = readProfiles (fileSystem , Objects .requireNonNull (profilesDir ), jacksonMapper );
7481 storedIdToSeatBid = readStoredData (fileSystem , Objects .requireNonNull (storedResponsesDir ));
7582 fileToCategories = readCategories (fileSystem , Objects .requireNonNull (categoriesDir ), jacksonMapper );
7683 }
@@ -98,6 +105,34 @@ private static Map<String, String> readStoredData(FileSystem fileSystem, String
98105 filepath -> fileSystem .readFileBlocking (filepath ).toString ()));
99106 }
100107
108+ private static Map <String , Set <StoredItem <Profile >>> readProfiles (FileSystem fileSystem ,
109+ String dir ,
110+ JacksonMapper jacksonMapper ) {
111+
112+ return fileSystem .readDirBlocking (dir ).stream ()
113+ .filter (filepath -> filepath .endsWith (JSON_SUFFIX ))
114+ .map (filepath -> readProfile (fileSystem , filepath , jacksonMapper ))
115+ .collect (Collectors .groupingBy (
116+ Map .Entry ::getKey ,
117+ Collectors .mapping (Map .Entry ::getValue , Collectors .toSet ())));
118+ }
119+
120+ private static Map .Entry <String , StoredItem <Profile >> readProfile (FileSystem fileSystem ,
121+ String profileFilePath ,
122+ JacksonMapper jacksonMapper ) {
123+
124+ final String profileFileName = StringUtils .removeEnd (new File (profileFilePath ).getName (), JSON_SUFFIX );
125+ final String [] accountIdAndProfileId = profileFileName .split ("-" );
126+ if (accountIdAndProfileId .length != 2 ) {
127+ throw new IllegalArgumentException ("Invalid name of profile file: " + profileFileName );
128+ }
129+
130+ final String profileAsString = fileSystem .readFileBlocking (profileFilePath ).toString ();
131+ final Profile profile = jacksonMapper .decodeValue (profileAsString , Profile .class );
132+
133+ return Map .entry (accountIdAndProfileId [1 ], StoredItem .of (accountIdAndProfileId [0 ], profile ));
134+ }
135+
101136 private static Map <String , Map <String , Category >> readCategories (FileSystem fileSystem ,
102137 String dir ,
103138 JacksonMapper jacksonMapper ) {
@@ -134,20 +169,22 @@ public Future<StoredDataResult<String>> getStoredData(String accountId,
134169 Set <String > impIds ,
135170 Timeout timeout ) {
136171
137- return CollectionUtils .isEmpty (requestIds ) && CollectionUtils .isEmpty (impIds )
172+ if (CollectionUtils .isEmpty (requestIds ) && CollectionUtils .isEmpty (impIds )) {
173+ return Future .succeededFuture (StoredDataResult .of (
174+ Collections .emptyMap (),
175+ Collections .emptyMap (),
176+ Collections .emptyList ()));
177+ }
138178
139- ? Future .succeededFuture (StoredDataResult .of (
140- Collections .emptyMap (),
141- Collections .emptyMap (),
142- Collections .emptyList ()))
179+ final Map <String , String > storedRequests = existingStoredIdToJson (requestIds , storedIdToRequest );
180+ final Map <String , String > storedImps = existingStoredIdToJson (impIds , storedIdToImp );
143181
144- : Future .succeededFuture (StoredDataResult .of (
145- existingStoredIdToJson (requestIds , storedIdToRequest ),
146- existingStoredIdToJson (impIds , storedIdToImp ),
147- Stream .of (
148- errorsForMissedIds (requestIds , storedIdToRequest , StoredDataType .request ),
149- errorsForMissedIds (impIds , storedIdToImp , StoredDataType .imp ))
150- .flatMap (Function .identity ())
182+ return Future .succeededFuture (StoredDataResult .of (
183+ storedRequests ,
184+ storedImps ,
185+ Stream .concat (
186+ errorsForMissedIds (requestIds , storedRequests .keySet (), StoredDataType .request .name ()),
187+ errorsForMissedIds (impIds , storedImps .keySet (), StoredDataType .imp .name ()))
151188 .toList ()));
152189 }
153190
@@ -175,19 +212,59 @@ public Future<StoredDataResult<Profile>> getProfiles(String accountId,
175212 Set <String > impIds ,
176213 Timeout timeout ) {
177214
178- // TODO: implement
179- return Future .failedFuture ("Not implemented" );
215+ if (CollectionUtils .isEmpty (requestIds ) && CollectionUtils .isEmpty (impIds )) {
216+ return Future .succeededFuture (StoredDataResult .of (
217+ Collections .emptyMap (),
218+ Collections .emptyMap (),
219+ Collections .emptyList ()));
220+ }
221+
222+ final List <String > errors = new ArrayList <>();
223+ final Map <String , Profile > requestProfiles = getProfiles (accountId , requestIds , Profile .Type .REQUEST , errors );
224+ final Map <String , Profile > impProfiles = getProfiles (accountId , requestIds , Profile .Type .IMP , errors );
225+
226+ return Future .succeededFuture (StoredDataResult .of (
227+ requestProfiles ,
228+ impProfiles ,
229+ Collections .unmodifiableList (errors )));
230+ }
231+
232+ private Map <String , Profile > getProfiles (String accountId ,
233+ Set <String > ids ,
234+ Profile .Type type ,
235+ List <String > errors ) {
236+
237+ final Map <String , Profile > result = new HashMap <>();
238+
239+ for (String id : ids ) {
240+ final Set <StoredItem <Profile >> profiles = SetUtils .predicatedSet (
241+ profileIdToProfile .getOrDefault (id , Collections .emptySet ()),
242+ storedItem -> storedItem .getData ().getType () == type );
243+
244+ try {
245+ final StoredItem <Profile > profile = StoredItemResolver
246+ .resolve (type .toString (), accountId , id , profiles );
247+
248+ result .put (id , profile .getData ());
249+ } catch (PreBidException e ) {
250+ errors .add (e .getMessage ());
251+ }
252+ }
253+
254+ return Collections .unmodifiableMap (result );
180255 }
181256
182257 @ Override
183258 public Future <StoredResponseDataResult > getStoredResponses (Set <String > responseIds , Timeout timeout ) {
184- return CollectionUtils .isEmpty (responseIds )
259+ if (CollectionUtils .isEmpty (responseIds )) {
260+ return Future .succeededFuture (StoredResponseDataResult .of (Collections .emptyMap (), Collections .emptyList ()));
261+ }
185262
186- ? Future . succeededFuture ( StoredResponseDataResult . of ( Collections . emptyMap (), Collections . emptyList ()))
263+ final Map < String , String > storedResponses = existingStoredIdToJson ( responseIds , storedIdToSeatBid );
187264
188- : Future .succeededFuture (StoredResponseDataResult .of (
189- existingStoredIdToJson ( responseIds , storedIdToSeatBid ) ,
190- errorsForMissedIds (responseIds , storedIdToSeatBid , StoredDataType .seatbid ).toList ()));
265+ return Future .succeededFuture (StoredResponseDataResult .of (
266+ storedResponses ,
267+ errorsForMissedIds (responseIds , storedResponses . keySet () , StoredDataType .seatbid . name () ).toList ()));
191268 }
192269
193270 @ Override
@@ -219,11 +296,8 @@ private static Map<String, String> existingStoredIdToJson(Set<String> requestedI
219296 .collect (Collectors .toMap (Function .identity (), storedIdToJson ::get ));
220297 }
221298
222- private static Stream <String > errorsForMissedIds (Set <String > ids ,
223- Map <String , String > storedIdToJson ,
224- StoredDataType type ) {
225-
226- return SetUtils .difference (ids , storedIdToJson .keySet ()).stream ()
299+ private static Stream <String > errorsForMissedIds (Set <String > requestedIds , Set <String > foundIds , String type ) {
300+ return SetUtils .difference (requestedIds , foundIds ).stream ()
227301 .map (id -> "No stored %s found for id: %s" .formatted (type , id ));
228302 }
229303}
0 commit comments