PROX-450: added eci decode from pares (#33)

This commit is contained in:
Anatoly Cherkasov 2020-08-25 12:59:47 +03:00 committed by GitHub
parent 14cad72da8
commit 239f555fd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 387 additions and 24 deletions

90
pom.xml
View File

@ -13,7 +13,7 @@
</parent>
<artifactId>adapter-common-lib</artifactId>
<version>0.0.26</version>
<version>0.0.27</version>
<packaging>jar</packaging>
<name>adapter-common-lib</name>
@ -39,16 +39,33 @@
<dockerfile.base.service.tag>bc95d0d6dc13c693acd2b274531a7d604b877bf3</dockerfile.base.service.tag>
<dockerfile.registry>${env.REGISTRY}</dockerfile.registry>
<shared.resources.version>0.3.6</shared.resources.version>
<jackson.version>2.11.2</jackson.version>
<apache.commons.lang3.version>3.9</apache.commons.lang3.version>
<apache.commons.codec.version>1.12</apache.commons.codec.version>
<damsel.version>1.439-b18f037</damsel.version>
<woody.version>[1.1.21,)</woody.version>
<cds-proto.version>1.62-07f2b0f</cds-proto.version>
<adapter-thrift-lib.version>1.0.5</adapter-thrift-lib.version>
<adapter-client-lib.version>2.1.27</adapter-client-lib.version>
<error-mapping-java.version>1.0.6</error-mapping-java.version>
<spring>5.2.8.RELEASE</spring>
<spring-boot>2.3.2.RELEASE</spring-boot>
<apache.commons.lang3.version>3.9</apache.commons.lang3.version>
<apache.commons.codec.version>1.12</apache.commons.codec.version>
<slf4j.version>1.7.30</slf4j.version>
<lombok.version>1.18.4</lombok.version>
<jackson.version>2.11.2</jackson.version>
<woody.version>[1.1.21,)</woody.version>
<jaxb-api.version>2.3.1</jaxb-api.version>
<jaxb-core.version>2.3.0.1</jaxb-core.version>
<jaxb-impl.version>2.3.2</jaxb-impl.version>
<javax.activation-api.version>1.2.0</javax.activation-api.version>
<logback.version>1.2.3</logback.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<damsel.version>1.439-b18f037</damsel.version>
<cds-proto.version>1.62-07f2b0f</cds-proto.version>
<logstash-logback-encoder.version>5.3</logstash-logback-encoder.version>
<error-mapping-java.version>1.0.6</error-mapping-java.version>
</properties>
<dependencies>
@ -70,51 +87,46 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
<version>${logback.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<version>${logback.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
<version>${logstash-logback-encoder.version}</version>
<scope>compile</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
<version>${spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.8.RELEASE</version>
<version>${spring}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.3.2.RELEASE</version>
<version>${spring-boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>2.3.2.RELEASE</version>
<version>${spring-boot}</version>
</dependency>
<!-- RBK.Money -->
@ -172,20 +184,50 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.3.2.RELEASE</version>
<version>${spring-boot}</version>
<scope>test</scope>
</dependency>
<!-- Other -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb-core.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb-impl.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>${javax.activation-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<version>${javax.servlet-api.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
<version>${validation-api.version}</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,20 @@
package com.rbkmoney.adapter.common.utils.mpi.constant;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Map;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EciDecodeState {
public static final String ECI_DECODE = "eci_decode_state";
public static final String ENABLED = "true";
public static final String DISABLED = "false";
public static boolean isEnabled(Map<String, String> options) {
String eciDecode = options.getOrDefault(EciDecodeState.ECI_DECODE, EciDecodeState.DISABLED);
return EciDecodeState.ENABLED.equalsIgnoreCase(eciDecode);
}
}

View File

@ -0,0 +1,16 @@
package com.rbkmoney.adapter.common.utils.mpi.exception;
public class ThreeDSecureException extends RuntimeException {
public ThreeDSecureException() {
super();
}
public ThreeDSecureException(String message) {
super(message);
}
public ThreeDSecureException(Throwable cause) {
super(cause);
}
public ThreeDSecureException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,22 @@
package com.rbkmoney.adapter.common.utils.mpi.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Getter
@Setter
@ToString
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Message")
public class Message {
@XmlElement(name = "PARes")
private PARes paRes;
}

View File

@ -0,0 +1,22 @@
package com.rbkmoney.adapter.common.utils.mpi.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Getter
@Setter
@ToString
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PARes")
public class PARes {
@XmlElement(name = "TX")
private TX tx;
}

View File

@ -0,0 +1,22 @@
package com.rbkmoney.adapter.common.utils.mpi.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Getter
@Setter
@ToString
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TX")
public class TX {
@XmlElement(name = "eci")
private String eci;
}

View File

@ -0,0 +1,22 @@
package com.rbkmoney.adapter.common.utils.mpi.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Getter
@Setter
@ToString
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ThreeDSecure")
public class ThreeDSecure {
@XmlElement(name = "Message")
private Message message;
}

View File

@ -0,0 +1,52 @@
package com.rbkmoney.adapter.common.utils.mpi.utils;
import com.rbkmoney.adapter.common.utils.mpi.exception.ThreeDSecureException;
import com.rbkmoney.adapter.common.utils.mpi.model.Message;
import com.rbkmoney.adapter.common.utils.mpi.model.PARes;
import com.rbkmoney.adapter.common.utils.mpi.model.TX;
import com.rbkmoney.adapter.common.utils.mpi.model.ThreeDSecure;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.util.Optional;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ThreeDSecureUtils {
private static JAXBContext jaxbContext;
static {
try {
jaxbContext = JAXBContext.newInstance(ThreeDSecure.class);
} catch (JAXBException ex) {
log.error("Failed to create jaxb context", ex);
throw new RuntimeException("Failed to create jaxb context", ex);
}
}
public static ThreeDSecure extractThreeDSecure(String str) {
try {
Unmarshaller jaxbMarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(str);
return (ThreeDSecure) jaxbMarshaller.unmarshal(reader);
} catch (JAXBException ex) {
log.error("Can't extract ThreeDSecure", ex);
throw new ThreeDSecureException(ex);
}
}
public static String extractEciFromPaRes(ThreeDSecure threeDSecure) {
return Optional.ofNullable(threeDSecure)
.map(ThreeDSecure::getMessage)
.map(Message::getPaRes)
.map(PARes::getTx)
.map(TX::getEci).orElse("");
}
}

View File

@ -0,0 +1,45 @@
package com.rbkmoney.adapter.common.utils.mpi.utils;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.zip.Inflater;
@Slf4j
public class UncompressDecoder {
private static final int START_OFFSET_IN_DATA = 0;
public static String decodePaRes(String str) {
return UncompressDecoder.decode(str);
}
public static String decode(String str) {
byte[] decode = Base64.getDecoder().decode(str.getBytes());
return new String(gzuncompress(decode));
}
private static byte[] gzuncompress(byte[] data) {
byte[] unCompressed = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
Inflater deCompressor = new Inflater();
try {
deCompressor.setInput(data);
final byte[] buf = new byte[1024];
while (!deCompressor.finished()) {
int count = deCompressor.inflate(buf);
bos.write(buf, START_OFFSET_IN_DATA, count);
}
unCompressed = bos.toByteArray();
bos.close();
} catch (Exception e) {
log.error("UnCompress Exception", e);
} finally {
deCompressor.end();
}
return unCompressed;
}
}

View File

@ -0,0 +1,24 @@
package com.rbkmoney.adapter.common.utils.mpi.constant;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;
public class EciDecodeStateTest {
@Test
public void isEciDecodeEnabled() {
Map<String, String> options = new HashMap<>();
assertFalse("Default disabled", EciDecodeState.isEnabled(options));
options.put(EciDecodeState.ECI_DECODE, EciDecodeState.ENABLED);
assertTrue("Excepted enabled", EciDecodeState.isEnabled(options));
options.put(EciDecodeState.ECI_DECODE, EciDecodeState.DISABLED);
assertFalse("Excepted disabled", EciDecodeState.isEnabled(options));
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,48 @@
package com.rbkmoney.adapter.common.utils.mpi.utils;
import com.rbkmoney.adapter.common.utils.mpi.model.Message;
import com.rbkmoney.adapter.common.utils.mpi.model.PARes;
import com.rbkmoney.adapter.common.utils.mpi.model.TX;
import com.rbkmoney.adapter.common.utils.mpi.model.ThreeDSecure;
import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertNotNull;
public class ThreeDSecureUtilsTest {
@Test
public void extractThreeDSecureUtils() {
ThreeDSecure threeDSecure = ThreeDSecureUtils.extractThreeDSecure(TestDataThreeDSecure.XML);
assertNotNull(threeDSecure);
assertNotNull(threeDSecure.getMessage().getPaRes().getTx().getEci());
assertEquals(TestDataThreeDSecure.ECI_05, threeDSecure.getMessage().getPaRes().getTx().getEci());
}
@Test
public void extractEciFromPaResTest() {
TX tx = new TX();
tx.setEci(TestDataThreeDSecure.ECI_05);
PARes paRes = new PARes();
paRes.setTx(tx);
Message message = new Message();
message.setPaRes(paRes);
ThreeDSecure threeDSecure = new ThreeDSecure();
threeDSecure.setMessage(message);
String eci = ThreeDSecureUtils.extractEciFromPaRes(threeDSecure);
assertEquals(TestDataThreeDSecure.ECI_05, eci);
threeDSecure.getMessage().getPaRes().getTx().setEci(TestDataThreeDSecure.ECI_07);
eci = ThreeDSecureUtils.extractEciFromPaRes(threeDSecure);
assertEquals(TestDataThreeDSecure.ECI_07, eci);
threeDSecure.getMessage().getPaRes().getTx().setEci(TestDataThreeDSecure.ECI_EMPTY);
eci = ThreeDSecureUtils.extractEciFromPaRes(threeDSecure);
assertEquals(TestDataThreeDSecure.ECI_EMPTY, eci);
}
}

View File

@ -0,0 +1,17 @@
package com.rbkmoney.adapter.common.utils.mpi.utils;
import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
public class UncompressDecoderTest {
@Test
public void decodeAndExtractThreeDSecure() {
String string = UncompressDecoder.decodePaRes(TestDataThreeDSecure.PARES);
assertNotNull(string);
assertEquals(TestDataThreeDSecure.XML, string);
}
}