/* * Copyright 2010-2017 Norwegian Agency for Public Management and eGovernment (Difi) * * Licensed under the EUPL, Version 1.1 or – as soon they * will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * * You may not use this work except in compliance with the Licence. * * You may obtain a copy of the Licence at: * * https://joinup.ec.europa.eu/community/eupl/og_page/eupl * * Unless required by applicable law or agreed to in * writing, software distributed under the Licence is * distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the Licence for the specific language governing * permissions and limitations under the Licence. */ package no.difi.oxalis.outbound.transmission; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import com.typesafe.config.Config; import no.difi.oxalis.api.lang.OxalisTransmissionException; import no.difi.oxalis.api.outbound.MessageSender; import no.difi.vefa.peppol.common.model.TransportProfile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; /** * Factory orchestrating available implementations of transport profiles. * * @author erlend */ class MessageSenderFactory { private static final Logger LOGGER = LoggerFactory.getLogger(MessageSenderFactory.class); /** * Guice injector used to load MessageSender implementation when needed, allows use of non-singleton * implementations. It is not considered best practice to inject injector like this, however in this case is this * suitable based on our requirements. */ private final Injector injector; /** * Map of configurations for supported transport profiles. */ private final Map<TransportProfile, Config> configMap; /** * Prioritized list of supported transport profiles. */ private final List<TransportProfile> prioritizedTransportProfiles; @Inject public MessageSenderFactory(Injector injector, Config config) { this.injector = injector; // Construct map of configuration for detected transport profiles. configMap = config.getObject("transport").keySet().stream() .map(key -> config.getConfig(String.format("transport.%s", key))) .collect(Collectors.toMap(c -> TransportProfile.of(c.getString("profile")), Function.identity())); // Create prioritized list of transport profiles. prioritizedTransportProfiles = Collections.unmodifiableList(configMap.values().stream() .filter(o -> !o.hasPath("enabled") || o.getBoolean("enabled")) .sorted((o1, o2) -> Integer.compare(o2.getInt("weight"), o1.getInt("weight"))) .map(o -> o.getString("profile")) .map(TransportProfile::of) .collect(Collectors.toList())); // Logging list of prioritized transport profiles supported. LOGGER.info("Prioritized list of transport profiles:"); prioritizedTransportProfiles .forEach(tp -> LOGGER.info("=> {}", tp.getValue())); } /** * Fetch list of supported transport profiles ordered by priority. * * @return List of supported transport profiles. */ public List<TransportProfile> getPrioritizedTransportProfiles() { return prioritizedTransportProfiles; } /** * Fetch identifier used in named annotation for the implementation of requested transport profile. * * @param transportProfile Identifier of transport profile requested. * @return String used in the named annotation. * @throws OxalisTransmissionException Thrown when transport profile is not supported. */ public String getSender(TransportProfile transportProfile) throws OxalisTransmissionException { if (!configMap.containsKey(transportProfile)) throw new OxalisTransmissionException( String.format("Transport protocol '%s' not supported.", transportProfile.getValue())); return configMap.get(transportProfile).getString("sender"); } /** * Fetch MessageSender implementing from provided transport profile. * * @param transportProfile Identifier of transport profile used to fetch MessageSender. * @return MessageSender implementing the transport profile requested. * @throws OxalisTransmissionException Thrown when loading of implementation fails or implementation is not found. */ public MessageSender getMessageSender(TransportProfile transportProfile) throws OxalisTransmissionException { return injector.getInstance(Key.get(MessageSender.class, Names.named(getSender(transportProfile)))); } }