Example usage for java.util Optional flatMap

List of usage examples for java.util Optional flatMap

Introduction

In this page you can find the example usage for java.util Optional flatMap.

Prototype

public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) 

Source Link

Document

If a value is present, returns the result of applying the given Optional -bearing mapping function to the value, otherwise returns an empty Optional .

Usage

From source file:com.ethercamp.harmony.service.PeersService.java

/**
 * Create MaxMind lookup service to find country by IP.
 * IPv6 is not used.//from ww  w  .ja  v a2s . c  o m
 */
private void createGeoDatabase() {
    final String[] countries = Locale.getISOCountries();
    final Optional<String> dbFilePath = Optional.ofNullable(env.getProperty("maxmind.file"));

    for (String country : countries) {
        Locale locale = new Locale("", country);
        localeMap.put(locale.getISO3Country().toUpperCase(), locale);
    }
    lookupService = dbFilePath.flatMap(path -> {
        try {
            return Optional.ofNullable(new LookupService(path,
                    LookupService.GEOIP_MEMORY_CACHE | LookupService.GEOIP_CHECK_CACHE));
        } catch (IOException e) {
            log.error("Problem finding maxmind database at " + path + ". " + e.getMessage());
            log.error(
                    "Wasn't able to create maxmind location service. Country information will not be available.");
            return Optional.empty();
        }
    });
}

From source file:alfio.controller.EventController.java

@RequestMapping(value = "/event/{eventName}/promoCode/{promoCode}", method = RequestMethod.POST)
@ResponseBody//from w  w  w. j a  va 2s.  c  o  m
public ValidationResult savePromoCode(@PathVariable("eventName") String eventName,
        @PathVariable("promoCode") String promoCode, Model model, HttpServletRequest request) {

    SessionUtil.removeSpecialPriceData(request);

    Optional<Event> optional = eventRepository.findOptionalByShortName(eventName);
    if (!optional.isPresent()) {
        return ValidationResult.failed(new ValidationResult.ErrorDescriptor("event", ""));
    }
    Event event = optional.get();
    ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
    Optional<String> maybeSpecialCode = Optional.ofNullable(StringUtils.trimToNull(promoCode));
    Optional<SpecialPrice> specialCode = maybeSpecialCode
            .flatMap((trimmedCode) -> specialPriceRepository.getByCode(trimmedCode));
    Optional<PromoCodeDiscount> promotionCodeDiscount = maybeSpecialCode
            .flatMap((trimmedCode) -> promoCodeRepository.findPromoCodeInEventOrOrganization(event.getId(),
                    trimmedCode));

    if (specialCode.isPresent()) {
        if (!optionally(() -> eventManager.getTicketCategoryById(specialCode.get().getTicketCategoryId(),
                event.getId())).isPresent()) {
            return ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ""));
        }

        if (specialCode.get().getStatus() != SpecialPrice.Status.FREE) {
            return ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ""));
        }

    } else if (promotionCodeDiscount.isPresent()
            && !promotionCodeDiscount.get().isCurrentlyValid(event.getZoneId(), now)) {
        return ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ""));
    } else if (!specialCode.isPresent() && !promotionCodeDiscount.isPresent()) {
        return ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ""));
    }

    if (maybeSpecialCode.isPresent() && !model.asMap().containsKey("hasErrors")) {
        if (specialCode.isPresent()) {
            SessionUtil.saveSpecialPriceCode(maybeSpecialCode.get(), request);
        } else if (promotionCodeDiscount.isPresent()) {
            SessionUtil.savePromotionCodeDiscount(maybeSpecialCode.get(), request);
        }
        return ValidationResult.success();
    }
    return ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ""));
}

From source file:alfio.controller.EventController.java

@RequestMapping(value = "/event/{eventName}", method = { RequestMethod.GET, RequestMethod.HEAD })
public String showEvent(@PathVariable("eventName") String eventName, Model model, HttpServletRequest request,
        Locale locale) {/*ww  w  . j  av  a 2s.  co m*/

    return eventRepository.findOptionalByShortName(eventName)
            .filter(e -> e.getStatus() != Event.Status.DISABLED).map(event -> {
                Optional<String> maybeSpecialCode = SessionUtil.retrieveSpecialPriceCode(request);
                Optional<SpecialPrice> specialCode = maybeSpecialCode
                        .flatMap((trimmedCode) -> specialPriceRepository.getByCode(trimmedCode));

                Optional<PromoCodeDiscount> promoCodeDiscount = SessionUtil
                        .retrievePromotionCodeDiscount(request).flatMap((code) -> promoCodeRepository
                                .findPromoCodeInEventOrOrganization(event.getId(), code));

                final ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
                //hide access restricted ticket categories
                List<TicketCategory> ticketCategories = ticketCategoryRepository
                        .findAllTicketCategories(event.getId());
                Map<Integer, String> categoriesDescription = ticketCategoryDescriptionRepository
                        .descriptionsByTicketCategory(ticketCategories.stream().map(TicketCategory::getId)
                                .collect(Collectors.toList()), locale.getLanguage());

                List<SaleableTicketCategory> saleableTicketCategories = ticketCategories.stream()
                        .filter((c) -> !c.isAccessRestricted() || (specialCode
                                .filter(sc -> sc.getTicketCategoryId() == c.getId()).isPresent()))
                        .map((m) -> new SaleableTicketCategory(m,
                                categoriesDescription.getOrDefault(m.getId(), ""), now, event,
                                ticketReservationManager.countAvailableTickets(event, m),
                                configurationManager.getIntConfigValue(
                                        Configuration.from(event.getOrganizationId(), event.getId(), m.getId(),
                                                ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION),
                                        5),
                                promoCodeDiscount.filter(promoCode -> shouldApplyDiscount(promoCode, m))
                                        .orElse(null)))
                        .collect(Collectors.toList());
                //

                final int orgId = event.getOrganizationId();
                final int eventId = event.getId();
                Map<ConfigurationKeys, Optional<String>> geoInfoConfiguration = configurationManager
                        .getStringConfigValueFrom(
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_PROVIDER),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_CLIENT_API_KEY),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_HERE_APP_ID),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_HERE_APP_CODE));

                LocationDescriptor ld = LocationDescriptor.fromGeoData(event.getLatLong(),
                        TimeZone.getTimeZone(event.getTimeZone()), geoInfoConfiguration);

                final boolean hasAccessPromotions = ticketCategoryRepository
                        .countAccessRestrictedRepositoryByEventId(event.getId()) > 0
                        || promoCodeRepository.countByEventAndOrganizationId(event.getId(),
                                event.getOrganizationId()) > 0;

                String eventDescription = eventDescriptionRepository
                        .findDescriptionByEventIdTypeAndLocale(event.getId(),
                                EventDescription.EventDescriptionType.DESCRIPTION, locale.getLanguage())
                        .orElse("");

                final EventDescriptor eventDescriptor = new EventDescriptor(event, eventDescription);
                List<SaleableTicketCategory> expiredCategories = saleableTicketCategories.stream()
                        .filter(SaleableTicketCategory::getExpired).collect(Collectors.toList());
                List<SaleableTicketCategory> validCategories = saleableTicketCategories.stream()
                        .filter(tc -> !tc.getExpired()).collect(Collectors.toList());
                List<SaleableAdditionalService> additionalServices = additionalServiceRepository
                        .loadAllForEvent(event.getId()).stream().map((as) -> getSaleableAdditionalService(event,
                                locale, as, promoCodeDiscount.orElse(null)))
                        .collect(Collectors.toList());
                Predicate<SaleableTicketCategory> waitingQueueTargetCategory = tc -> !tc.getExpired()
                        && !tc.isBounded();
                boolean validPaymentConfigured = isEventHasValidPaymentConfigurations(event,
                        configurationManager);

                List<SaleableAdditionalService> notExpiredServices = additionalServices.stream()
                        .filter(SaleableAdditionalService::isNotExpired).collect(Collectors.toList());

                List<SaleableAdditionalService> supplements = adjustIndex(0,
                        notExpiredServices.stream()
                                .filter(a -> a.getType() == AdditionalService.AdditionalServiceType.SUPPLEMENT)
                                .collect(Collectors.toList()));
                List<SaleableAdditionalService> donations = adjustIndex(supplements.size(),
                        notExpiredServices.stream()
                                .filter(a -> a.getType() == AdditionalService.AdditionalServiceType.DONATION)
                                .collect(Collectors.toList()));

                model.addAttribute("event", eventDescriptor)//
                        .addAttribute("organization", organizationRepository.getById(event.getOrganizationId()))
                        .addAttribute("ticketCategories", validCategories)//
                        .addAttribute("expiredCategories", expiredCategories)//
                        .addAttribute("containsExpiredCategories", !expiredCategories.isEmpty())//
                        .addAttribute("showNoCategoriesWarning", validCategories.isEmpty())
                        .addAttribute("hasAccessPromotions", hasAccessPromotions)
                        .addAttribute("promoCode", specialCode.map(SpecialPrice::getCode).orElse(null))
                        .addAttribute("locationDescriptor", ld)
                        .addAttribute("pageTitle", "show-event.header.title")
                        .addAttribute("hasPromoCodeDiscount", promoCodeDiscount.isPresent())
                        .addAttribute("promoCodeDiscount", promoCodeDiscount.orElse(null))
                        .addAttribute("displayWaitingQueueForm",
                                EventUtil.displayWaitingQueueForm(event, saleableTicketCategories,
                                        configurationManager, eventStatisticsManager.noSeatsAvailable()))
                        .addAttribute("displayCategorySelectionForWaitingQueue",
                                saleableTicketCategories.stream().filter(waitingQueueTargetCategory)
                                        .count() > 1)
                        .addAttribute("unboundedCategories",
                                saleableTicketCategories.stream().filter(waitingQueueTargetCategory)
                                        .collect(Collectors.toList()))
                        .addAttribute("preSales", EventUtil.isPreSales(event, saleableTicketCategories))
                        .addAttribute("userLanguage", locale.getLanguage())
                        .addAttribute("showAdditionalServices", !notExpiredServices.isEmpty())
                        .addAttribute("showAdditionalServicesDonations", !donations.isEmpty())
                        .addAttribute("showAdditionalServicesSupplements", !supplements.isEmpty())
                        .addAttribute("enabledAdditionalServicesDonations", donations)
                        .addAttribute("enabledAdditionalServicesSupplements", supplements)
                        .addAttribute("forwardButtonDisabled",
                                (saleableTicketCategories.stream()
                                        .noneMatch(SaleableTicketCategory::getSaleable))
                                        || !validPaymentConfigured)
                        .addAttribute("useFirstAndLastName", event.mustUseFirstAndLastName())
                        .addAttribute("validPaymentMethodAvailable", validPaymentConfigured)
                        .addAttribute("validityStart", event.getBegin())
                        .addAttribute("validityEnd", event.getEnd());

                model.asMap().putIfAbsent("hasErrors", false);//
                return "/event/show-event";
            }).orElse(REDIRECT + "/");
}

From source file:com.ikanow.aleph2.example.flume_harvester.services.FlumeHarvesterSink.java

/** Outputs data directly into the Aleph2 data services without going via batch or streaming enrichment
 * @param json/*from  ww  w.  j  av a 2  s . c o m*/
 * @param config
 */
protected void directOutput(final JsonNode json, FlumeBucketConfigBean config, final DataBucketBean bucket) {
    try {
        // Lazy initialization

        if (!_direct.isSet()) {
            final DirectOutputState direct = new DirectOutputState();

            // Search index service

            final Optional<ISearchIndexService> search_index_service = (config.output().direct_output()
                    .contains("search_index_service") ? _context.getServiceContext().getSearchIndexService()
                            : Optional.empty());

            direct.search_index_service = search_index_service.flatMap(IDataServiceProvider::getDataService)
                    .flatMap(s -> s.getWritableDataService(JsonNode.class, bucket, Optional.empty(),
                            Optional.empty()));

            direct.batch_search_index_service = direct.search_index_service
                    .flatMap(IDataWriteService::getBatchWriteSubservice);

            // Storage service

            final Optional<IStorageService> storage_service = (config.output().direct_output()
                    .contains("storage_service") ? Optional.of(_context.getServiceContext().getStorageService())
                            : Optional.empty());

            direct.storage_service = storage_service.flatMap(IDataServiceProvider::getDataService)
                    .flatMap(s -> s.getWritableDataService(JsonNode.class, bucket,
                            Optional.of(IStorageService.StorageStage.processed.toString()), Optional.empty()));

            direct.bulk_storage_service = direct.storage_service
                    .flatMap(IDataWriteService::getBatchWriteSubservice);

            // Batch input (uses storage service logic)

            final Optional<IStorageService> batch_input_service = (config.output().direct_output()
                    .contains("batch") ? Optional.of(_context.getServiceContext().getStorageService())
                            : Optional.empty());

            direct.batch_input_service = batch_input_service.flatMap(IDataServiceProvider::getDataService)
                    .flatMap(s -> s.getWritableDataService(JsonNode.class, bucket,
                            Optional.of(IStorageService.StorageStage.transient_input.toString()
                                    + Optionals.of(() -> _config.get().output().batch_schema())
                                            .map(b -> BeanTemplateUtils.toJson(b).toString())
                                            .map(str -> ":" + str).orElse("")),
                            Optional.empty()));

            direct.bulk_batch_input_service = direct.batch_input_service
                    .flatMap(IDataWriteService::getBatchWriteSubservice);

            direct.also_stream = config.output().direct_output().contains("stream");

            _direct.set(direct);
        }
        final DirectOutputState direct = _direct.get();

        // Search index service

        direct.search_index_service.ifPresent(search_index_service -> {
            if (direct.batch_search_index_service.isPresent()) {
                direct.batch_search_index_service.get().storeObject(json);
            } else {
                search_index_service.storeObject(json);
            }
        });

        // Storage service

        direct.storage_service.ifPresent(storage_service -> {
            if (direct.bulk_storage_service.isPresent()) {
                direct.bulk_storage_service.get().storeObject(json);
            } else {
                storage_service.storeObject(json);
            }
        });

        //Batch input (uses storage service logic)

        direct.batch_input_service.ifPresent(storage_service -> {
            if (direct.bulk_batch_input_service.isPresent()) {
                direct.bulk_batch_input_service.get().storeObject(json);
            } else {
                storage_service.storeObject(json);
            }
        });

        // Streaming

        if (direct.also_stream) {
            _context.sendObjectToStreamingPipeline(Optional.empty(), Either.left(json));
        }
    } catch (Throwable t) {
        //DEBUG
        //System.out.println(ErrorUtils.getLongForm("{0}", t));
        //DEBUG
        //_logger.warn("Error", t);
    }
}

From source file:com.ethercamp.harmony.service.BlockchainInfoService.java

@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof EmbeddedServletContainerInitializedEvent) {
        serverPort = ((EmbeddedServletContainerInitializedEvent) event).getEmbeddedServletContainer().getPort();

        final boolean isPrivateNetwork = env.getProperty("networkProfile", "").equalsIgnoreCase("private");
        final boolean isClassicNetwork = env.getProperty("networkProfile", "").equalsIgnoreCase("classic");

        // find out network name
        final Optional<String> blockHash = Optional.ofNullable(blockchain.getBlockByNumber(0l))
                .map(block -> Hex.toHexString(block.getHash()));
        final Pair<String, Optional<String>> networkInfo;
        if (isPrivateNetwork) {
            networkInfo = Pair.of("Private Miner Network", Optional.empty());
        } else if (isClassicNetwork) {
            networkInfo = Pair.of("Classic ETC", Optional.empty());
        } else {/*w w w. java 2  s .c o  m*/
            networkInfo = blockHash
                    .flatMap(hash -> Optional.ofNullable(BlockchainConsts.getNetworkInfo(env, hash)))
                    .orElse(Pair.of("Unknown network", Optional.empty()));
        }

        final boolean isContractsFeatureEnabled = env.getProperty("feature.contract.enabled", "false")
                .equalsIgnoreCase("true");
        if (!isContractsFeatureEnabled) {
            VM.setVmHook(null);
            log.info("Disabled VM hook due to contracts feature disabled");
        }

        initialInfo.set(new InitialInfoDTO(config.projectVersion() + "-" + config.projectVersionModifier(),
                "Hash: " + BuildInfo.buildHash + ",   Created: " + BuildInfo.buildTime,
                env.getProperty("app.version"), networkInfo.getFirst(), networkInfo.getSecond().orElse(null),
                blockHash.orElse(null), System.currentTimeMillis(), Hex.toHexString(config.nodeId()),
                serverPort, isPrivateNetwork, env.getProperty("portCheckerUrl"), config.bindIp(),
                isContractsFeatureEnabled));

        final String ANSI_RESET = "\u001B[0m";
        final String ANSI_BLUE = "\u001B[34m";
        System.out.println("EthereumJ database dir location: " + systemProperties.databaseDir());
        System.out.println("EthereumJ keystore dir location: " + keystore.getKeyStoreLocation());
        System.out.println(ANSI_BLUE + "Server started at http://localhost:" + serverPort + "" + ANSI_RESET);

        if (!config.getConfig().hasPath("logs.keepStdOut")
                || !config.getConfig().getBoolean("logs.keepStdOut")) {
            createLogAppenderForMessaging();
        }
    }
}

From source file:com.spotify.heroic.metadata.elasticsearch.ElasticsearchMetadataModule.java

@JsonCreator
public ElasticsearchMetadataModule(@JsonProperty("id") Optional<String> id,
        @JsonProperty("groups") Optional<Groups> groups,
        @JsonProperty("connection") Optional<ConnectionModule> connection,
        @JsonProperty("writesPerSecond") Optional<Double> writesPerSecond,
        @JsonProperty("rateLimitSlowStartSeconds") Optional<Long> rateLimitSlowStartSeconds,
        @JsonProperty("writeCacheDurationMinutes") Optional<Long> writeCacheDurationMinutes,
        @JsonProperty("deleteParallelism") Optional<Integer> deleteParallelism,
        @JsonProperty("templateName") Optional<String> templateName,
        @JsonProperty("backendType") Optional<String> backendType,
        @JsonProperty("configure") Optional<Boolean> configure) {
    this.id = id;
    this.groups = groups.orElseGet(Groups::empty).or(DEFAULT_GROUP);
    this.connection = connection.orElseGet(ConnectionModule::buildDefault);
    this.writesPerSecond = writesPerSecond.orElse(DEFAULT_WRITES_PER_SECOND);
    this.rateLimitSlowStartSeconds = rateLimitSlowStartSeconds.orElse(DEFAULT_RATE_LIMIT_SLOW_START_SECONDS);
    this.writeCacheDurationMinutes = writeCacheDurationMinutes.orElse(DEFAULT_WRITE_CACHE_DURATION_MINUTES);
    this.deleteParallelism = deleteParallelism.orElse(DEFAULT_DELETE_PARALLELISM);
    this.templateName = templateName.orElse(DEFAULT_TEMPLATE_NAME);
    this.backendTypeBuilder = backendType.flatMap(bt -> ofNullable(backendTypes.get(bt))).orElse(defaultSetup);
    this.configure = configure.orElse(false);
}

From source file:com.ikanow.aleph2.search_service.elasticsearch.services.ElasticsearchIndexService.java

/** A slightly generic function that determines what roles this service is playing
 * @param bucket/* www .j a v a 2s.  co m*/
 * @param service_clazz
 * @param maybe_schema
 * @return
 */
protected <I extends IUnderlyingService, T> boolean isServiceFor(final DataBucketBean bucket,
        final Class<I> service_clazz, Optional<T> maybe_schema) {
    return maybe_schema.flatMap(Lambdas.maybeWrap_i(schema -> {
        final JsonNode schema_map = BeanTemplateUtils.toJson(schema);
        final JsonNode enabled = schema_map.get("enabled");

        if ((null != enabled) && enabled.isBoolean() && !enabled.asBoolean()) {
            return false;
        } else {
            final Optional<I> maybe_service = _service_context.getService(service_clazz,
                    Optional.ofNullable(schema_map.get("service_name")).<String>map(j -> j.asText()));

            return maybe_service.map(service -> this.getClass().equals(service.getClass())).orElse(false);
        }
    })).orElse(false);
}

From source file:it.tidalwave.bluemarine2.metadata.impl.audio.musicbrainz.MusicBrainzAudioMedatataImporter.java

/*******************************************************************************************************************
 *
 * Extracts data from the given {@link DefTrackData}.
 *
 * @param   rmd                     the release
 * @param   cddb                    the CDDB of the track we're handling
 * @param   track                   the track
 * @return                          the RDF triples
 * @throws  InterruptedException    in case of I/O error
 * @throws  IOException             in case of I/O error
 *
 ******************************************************************************************************************/
@Nonnull/*from  w  w  w.  j  a  v  a  2s. co m*/
private ModelBuilder handleTrack(final @Nonnull ReleaseMediumDisk rmd, final @Nonnull Cddb cddb,
        final @Nonnull IRI recordIri, final @Nonnull DefTrackData track)
        throws IOException, InterruptedException {
    final IRI trackIri = trackIriOf(track.getId());
    final int trackNumber = track.getPosition().intValue();
    final Optional<Integer> diskCount = emptyIfOne(rmd.getDiskCount());
    final Optional<Integer> diskNumber = diskCount.flatMap(dc -> rmd.getDiskNumber());
    final String recordingId = track.getRecording().getId();
    //                final Recording recording = track.getRecording();
    final Recording recording = mbMetadataProvider.getResource(RECORDING, recordingId, RECORDING_INCLUDES)
            .get();
    final String trackTitle = recording.getTitle();
    //                    track.getRecording().getAliasList().getAlias().get(0).getSortName();
    final IRI signalIri = signalIriFor(cddb, track.getPosition().intValue());
    log.info(">>>>>>>> {}. {}", trackNumber, trackTitle);

    return createModelBuilder().with(recordIri, MO.P_TRACK, trackIri)
            .with(recordIri, BMMO.P_DISK_COUNT, literalForInt(diskCount))
            .with(recordIri, BMMO.P_DISK_NUMBER, literalForInt(diskNumber))

            .with(signalIri, MO.P_PUBLISHED_AS, trackIri)

            .with(trackIri, RDF.TYPE, MO.C_TRACK).with(trackIri, RDFS.LABEL, literalFor(trackTitle))
            .with(trackIri, DC.TITLE, literalFor(trackTitle))
            .with(trackIri, BMMO.P_IMPORTED_FROM, BMMO.O_SOURCE_MUSICBRAINZ)
            .with(trackIri, MO.P_TRACK_NUMBER, literalFor(trackNumber))
            .with(trackIri, MO.P_MUSICBRAINZ_GUID, literalFor(track.getId()))
            .with(trackIri, MO.P_MUSICBRAINZ, musicBrainzIriFor("track", track.getId()))

            .with(handleTrackRelations(signalIri, trackIri, recordIri, recording));
}

From source file:alfio.manager.TicketReservationManager.java

private boolean isAdmin(Optional<UserDetails> userDetails) {
    return userDetails.flatMap(u -> u.getAuthorities().stream().map(a -> Role.fromRoleName(a.getAuthority()))
            .filter(Role.ADMIN::equals).findFirst()).isPresent();
}

From source file:alfio.manager.TicketReservationManager.java

/**
 * Create a ticket reservation. It will create a reservation _only_ if it can find enough tickets. Note that it will not do date/validity validation. This must be ensured by the
 * caller.//  www . ja  v  a 2s . c o m
 *
 * @param event
 * @param list
 * @param reservationExpiration
 * @param forWaitingQueue
 * @return
 */
public String createTicketReservation(Event event, List<TicketReservationWithOptionalCodeModification> list,
        List<ASReservationWithOptionalCodeModification> additionalServices, Date reservationExpiration,
        Optional<String> specialPriceSessionId, Optional<String> promotionCodeDiscount, Locale locale,
        boolean forWaitingQueue)
        throws NotEnoughTicketsException, MissingSpecialPriceTokenException, InvalidSpecialPriceTokenException {
    String reservationId = UUID.randomUUID().toString();

    Optional<PromoCodeDiscount> discount = promotionCodeDiscount
            .flatMap((promoCodeDiscount) -> promoCodeDiscountRepository
                    .findPromoCodeInEventOrOrganization(event.getId(), promoCodeDiscount));

    ticketReservationRepository.createNewReservation(reservationId, reservationExpiration,
            discount.map(PromoCodeDiscount::getId).orElse(null), locale.getLanguage(), event.getId(),
            event.getVat(), event.isVatIncluded());
    list.forEach(t -> reserveTicketsForCategory(event, specialPriceSessionId, reservationId, t, locale,
            forWaitingQueue, discount.orElse(null)));

    int ticketCount = list.stream().map(TicketReservationWithOptionalCodeModification::getAmount)
            .mapToInt(Integer::intValue).sum();

    // apply valid additional service with supplement policy mandatory one for ticket
    additionalServiceRepository
            .findAllInEventWithPolicy(event.getId(),
                    AdditionalService.SupplementPolicy.MANDATORY_ONE_FOR_TICKET)
            .stream().filter(AdditionalService::getSaleable).forEach(as -> {
                AdditionalServiceReservationModification asrm = new AdditionalServiceReservationModification();
                asrm.setAdditionalServiceId(as.getId());
                asrm.setQuantity(ticketCount);
                reserveAdditionalServicesForReservation(event.getId(), reservationId,
                        new ASReservationWithOptionalCodeModification(asrm, Optional.empty()),
                        discount.orElse(null));
            });

    additionalServices.forEach(as -> reserveAdditionalServicesForReservation(event.getId(), reservationId, as,
            discount.orElse(null)));

    TicketReservation reservation = ticketReservationRepository.findReservationById(reservationId);

    OrderSummary orderSummary = orderSummaryForReservationId(reservation.getId(), event,
            Locale.forLanguageTag(reservation.getUserLanguage()));
    ticketReservationRepository.addReservationInvoiceOrReceiptModel(reservationId, Json.toJson(orderSummary));

    auditingRepository.insert(reservationId, null, event.getId(), Audit.EventType.RESERVATION_CREATE,
            new Date(), Audit.EntityType.RESERVATION, reservationId);

    return reservationId;
}