From 5ee2fdd40732aa8eca29e89b14fa5238385868e8 Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Tue, 16 Apr 2019 11:49:56 +0200 Subject: Store incoming delivery request on redis server - Connect to Redis server and implement RedisRepository - Add redis dependencies (spring-boot-starter, jedis, apache commons io). Latter dependencies are apparently needed and not included in the sprint-boot-starter; See https://github.com/spring-projects/spring-boot/issues/5718 and https://www.concretepage.com/questions/599 - Connect DeliveryRequestHandler to RedisRepository - Rewrote Marshalling: replace JaxbContext with spring-oxm JaxbMarshaller - Catch and log all exceptions in App2MZSService; Former: certain exceptions would go unnoticed, e.g. ConnectionRefused --- src/main/java/at/gv/egiz/moazs/App2MzsService.java | 14 +++-- .../at/gv/egiz/moazs/DeliveryRequestHandler.java | 17 +++++- src/main/java/at/gv/egiz/moazs/MyMarshaller.java | 54 ++++++------------ src/main/java/at/gv/egiz/moazs/RedisConfig.java | 64 ++++++++++++++++++++++ .../java/at/gv/egiz/moazs/RedisRepository.java | 57 +++++++++++++++++++ src/main/resources/application.properties | 2 + 6 files changed, 166 insertions(+), 42 deletions(-) create mode 100644 src/main/java/at/gv/egiz/moazs/RedisConfig.java create mode 100644 src/main/java/at/gv/egiz/moazs/RedisRepository.java create mode 100644 src/main/resources/application.properties (limited to 'src/main') diff --git a/src/main/java/at/gv/egiz/moazs/App2MzsService.java b/src/main/java/at/gv/egiz/moazs/App2MzsService.java index 2f06f7b..f8c00fc 100644 --- a/src/main/java/at/gv/egiz/moazs/App2MzsService.java +++ b/src/main/java/at/gv/egiz/moazs/App2MzsService.java @@ -2,6 +2,8 @@ package at.gv.egiz.moazs; import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs.App2MzsPortType; import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -16,6 +18,8 @@ import static java.util.concurrent.CompletableFuture.supplyAsync; @Service public class App2MzsService implements App2MzsPortType { + private static final Logger logger = LoggerFactory.getLogger(App2MzsService.class); + //TODO move timeout to config private final int timeoutForAnwser = 10; private final String MZSTNS = "http://reference.e-government.gv.at/namespace/zustellung/mzs/app2mzs#"; @@ -40,14 +44,16 @@ public class App2MzsService implements App2MzsPortType { try { return future.get(timeoutForAnwser, TimeUnit.SECONDS); - - } catch (InterruptedException | ExecutionException e) { - return generateErrorResponse(); - } catch (TimeoutException e) { future.thenAccept(appClient::sendNotification); + logger.warn("Answer Timed Out", e); return generatePartialSuccessResponse(deliveryRequest); + + } catch (Exception e ) { + logger.error("Could not deliver request.", e); + return generateErrorResponse(); } + } private DeliveryResponseType generatePartialSuccessResponse(DeliveryRequestType deliveryRequest) { diff --git a/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java b/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java index c5ecdb5..16235cf 100644 --- a/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java +++ b/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java @@ -2,23 +2,36 @@ package at.gv.egiz.moazs; import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType; import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryResponseType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.xml.bind.JAXBElement; import java.util.function.Function; @Component public class DeliveryRequestHandler implements Function { + private static final Logger logger = LoggerFactory.getLogger(DeliveryRequestHandler.class); + + @Autowired + private RedisRepository repository; /** * Handles the Delivery Request */ @Override - public DeliveryResponseType apply(DeliveryRequestType deliveryRequestType) { + public DeliveryResponseType apply(DeliveryRequestType deliveryRequest) { + + var deliveryId = deliveryRequest.getMetaData().getAppDeliveryID(); + logger.info(String.format("Received Request with AppDeliveryID = %s", deliveryId)); //check if DR is complete - // + + //store delivery request + repository.add(deliveryRequest); return null; } diff --git a/src/main/java/at/gv/egiz/moazs/MyMarshaller.java b/src/main/java/at/gv/egiz/moazs/MyMarshaller.java index 609a3c8..ea14a0f 100644 --- a/src/main/java/at/gv/egiz/moazs/MyMarshaller.java +++ b/src/main/java/at/gv/egiz/moazs/MyMarshaller.java @@ -1,51 +1,33 @@ package at.gv.egiz.moazs; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.stereotype.Component; -import javax.xml.bind.*; -import java.io.ByteArrayInputStream; +import javax.xml.transform.Result; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.InputStream; import java.io.StringWriter; +/** + * @author xerx593 + * Source: https://stackoverflow.com/questions/44676532/how-to-use-spring-to-marshal-and-unmarshal-xml + */ @Component public class MyMarshaller { -// @Value("classpath:mzs/app2mzs.xsd") -// private Resource mzsSchema; -// -// @Value("classpath:mzs/mzs_mypersondata_en.xsd") -// private Resource mzsPersonSchema; -// -// @Value("classpath:zusemsg/zuse_p2.xsd") -// private Resource msgSchema; -// -// @Value("classpath:zusemsg/zuse_mypersondata_en_p2.xsd") -// private Resource msgPersonSchema; - - @Autowired - private JAXBContext context; - - public byte[] toBytes(JAXBElement element) { - try { - Marshaller marshaller = context.createMarshaller(); - StringWriter sw = new StringWriter(); - marshaller.marshal(element, sw); - return sw.toString().getBytes(); - } catch (JAXBException e) { - throw new RuntimeException(e); - } - } - - public JAXBElement toJAXBElement(byte[] bytes) { - try { - Unmarshaller unmarshaller = context.createUnmarshaller(); + private Jaxb2Marshaller marshaller; - var stream = new ByteArrayInputStream(bytes); - return (JAXBElement) unmarshaller.unmarshal(stream); + public String marshallXml(final T obj) { + StringWriter sw = new StringWriter(); + Result result = new StreamResult(sw); + marshaller.marshal(obj, result); + return sw.toString(); + } - } catch (JAXBException e) { - throw new RuntimeException(e); - } + public T unmarshallXml(final InputStream xml) { + return (T) marshaller.unmarshal(new StreamSource(xml)); } } diff --git a/src/main/java/at/gv/egiz/moazs/RedisConfig.java b/src/main/java/at/gv/egiz/moazs/RedisConfig.java new file mode 100644 index 0000000..3487eb5 --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/RedisConfig.java @@ -0,0 +1,64 @@ +package at.gv.egiz.moazs; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericToStringSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +import java.util.HashMap; + +@Configuration +@PropertySource("classpath:application.properties") +public class RedisConfig { + + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.port}") + private int port; + + @Bean + JedisConnectionFactory jedisConnectionFactory() { + RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); + config.setHostName(host); + config.setPort(port); + return new JedisConnectionFactory(config); + } + + @Bean + public StringRedisSerializer stringRedisSerializer() { + return new StringRedisSerializer(); + } + + @Bean + public RedisTemplate redisTemplate() { + final RedisTemplate template = new RedisTemplate(); + template.setConnectionFactory(jedisConnectionFactory()); + template.setDefaultSerializer(stringRedisSerializer()); + return template; + } + + @Bean + public Jaxb2Marshaller jaxb2Marshaller() { + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound( + at.gv.e_government.reference.namespace.zustellung.mzs.persondata_.ObjectFactory.class, + at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.ObjectFactory.class, + at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.ObjectFactory.class, + at.gv.e_government.reference.namespace.persondata.phase2._20181206_.ObjectFactory.class); //"alternatively" setContextPath(), + + marshaller.setMarshallerProperties(new HashMap() {{ + put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true); + }}); + + return marshaller; + } + + +} diff --git a/src/main/java/at/gv/egiz/moazs/RedisRepository.java b/src/main/java/at/gv/egiz/moazs/RedisRepository.java new file mode 100644 index 0000000..dfc68ea --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/RedisRepository.java @@ -0,0 +1,57 @@ +package at.gv.egiz.moazs; + +import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType; +import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.ObjectFactory; +import org.apache.tools.ant.filters.StringInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import javax.xml.bind.JAXBElement; + +@Repository +public class RedisRepository { + + private static final Logger logger = LoggerFactory.getLogger(RedisRepository.class); + + private static final String KEY = "MZS_DELIVERY_REQUEST"; + + private final RedisTemplate redisTemplate; + + private final MyMarshaller marshaller; + + private HashOperations hashOperations; + + private final ObjectFactory factory = new ObjectFactory(); + + @Autowired + public RedisRepository(RedisTemplate redisTemplate, MyMarshaller marshaller){ + this.redisTemplate = redisTemplate; + this.marshaller = marshaller; + } + + @PostConstruct + private void init(){ + hashOperations = redisTemplate.opsForHash(); + } + + public void add(DeliveryRequestType request) { + var hashKey = request.getMetaData().getAppDeliveryID(); + var serializedRequest = marshaller.marshallXml(factory.createDeliveryRequest(request)); + + logger.info("Adding DeliveryRequest to repository: AppDeliveryId = {}, request = {}", hashKey, serializedRequest); + hashOperations.put(KEY, hashKey, serializedRequest); + + var drs = (String) hashOperations.get(KEY, hashKey); + var requestFromRedis = (JAXBElement) marshaller.unmarshallXml(new StringInputStream(drs)); + String appDeliveryID = requestFromRedis.getValue().getMetaData().getAppDeliveryID(); + logger.info("here's what i got out of redis: appDeliveryId = {}, request = {}", appDeliveryID, drs); + + + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..7cf70bd --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.redis.host=172.17.0.2 +spring.redis.port=6379 -- cgit v1.2.3