mirror of
https://github.com/valitydev/proxy-mocketbank-mpi.git
synced 2024-11-06 08:25:16 +00:00
parent
bd9a8d668d
commit
1fbe467baf
51
Jenkinsfile
vendored
51
Jenkinsfile
vendored
@ -1,47 +1,18 @@
|
|||||||
#!groovy
|
#!groovy
|
||||||
build('proxy-mocketbank-mpi', 'java-maven') {
|
build('proxy-mocketbank-mpi', 'java-maven') {
|
||||||
checkoutRepo()
|
checkoutRepo()
|
||||||
|
loadBuildUtils()
|
||||||
|
|
||||||
|
def javaServicePipeline
|
||||||
|
runStage('load JavaService pipeline') {
|
||||||
|
javaServicePipeline = load("build_utils/jenkins_lib/pipeJavaService.groovy")
|
||||||
|
}
|
||||||
|
|
||||||
def serviceName = env.REPO_NAME
|
def serviceName = env.REPO_NAME
|
||||||
def mvnArgs = '-DjvmArgs="-Xmx256m"'
|
def mvnArgs = '-DjvmArgs="-Xmx256m"'
|
||||||
|
def useJava11 = true
|
||||||
|
def registry = 'dr2.rbkmoney.com'
|
||||||
|
def registryCredsId = 'jenkins_harbor'
|
||||||
|
|
||||||
// Run mvn and generate docker file
|
javaServicePipeline(serviceName, useJava11, mvnArgs, registry, registryCredsId)
|
||||||
runStage('Maven package') {
|
}
|
||||||
withCredentials([[$class: 'FileBinding', credentialsId: 'java-maven-settings.xml', variable: 'SETTINGS_XML']]) {
|
|
||||||
def mvn_command_arguments = ' --batch-mode --settings $SETTINGS_XML -P ci ' +
|
|
||||||
" -Dgit.branch=${env.BRANCH_NAME} " +
|
|
||||||
" ${mvnArgs}"
|
|
||||||
if (env.BRANCH_NAME == 'master') {
|
|
||||||
sh 'mvn deploy' + mvn_command_arguments
|
|
||||||
} else {
|
|
||||||
sh 'mvn package' + mvn_command_arguments
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def serviceImage;
|
|
||||||
def imgShortName = 'rbkmoney/' + "${serviceName}" + ':' + '$COMMIT_ID';
|
|
||||||
getCommitId()
|
|
||||||
runStage('Build Service image') {
|
|
||||||
serviceImage = docker.build(imgShortName, '-f ./target/Dockerfile ./target')
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (env.BRANCH_NAME == 'master') {
|
|
||||||
runStage('Push Service image') {
|
|
||||||
docker.withRegistry('https://dr.rbkmoney.com/v2/', 'dockerhub-rbkmoneycibot') {
|
|
||||||
serviceImage.push();
|
|
||||||
}
|
|
||||||
// Push under 'withRegistry' generates 2d record with 'long name' in local docker registry.
|
|
||||||
// Untag the long-name
|
|
||||||
sh "docker rmi dr.rbkmoney.com/${imgShortName}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
runStage('Remove local image') {
|
|
||||||
// Remove the image to keep Jenkins runner clean.
|
|
||||||
sh "docker rmi ${imgShortName}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 0a57c5f10795d77ecf121d509fde7c654175c3c1
|
Subproject commit ea4aa042f482551d624fd49a570d28488f479e93
|
52
pom.xml
52
pom.xml
@ -7,12 +7,12 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.rbkmoney</groupId>
|
<groupId>com.rbkmoney</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.5.1.RELEASE</version>
|
<version>2.1.1.RELEASE</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>proxy-mocketbank-mpi</artifactId>
|
<artifactId>proxy-mocketbank-mpi</artifactId>
|
||||||
<version>1.0.5-SNAPSHOT</version>
|
<version>1.0.6-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>proxy-mocketbank-mpi</name>
|
<name>proxy-mocketbank-mpi</name>
|
||||||
@ -20,10 +20,13 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<server.port>8080</server.port>
|
<server.port>8080</server.port>
|
||||||
|
<exposed.ports>${server.port}</exposed.ports>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.maintainer>Anatoly Cherkasov <a.cherkasov@rbkmoney.com></project.maintainer>
|
<project.maintainer>Anatoly Cherkasov <a.cherkasov@rbkmoney.com></project.maintainer>
|
||||||
<dockerfile.base.service.tag>22c57470c4fc47161894f036b7cf9d70f42b75f5</dockerfile.base.service.tag>
|
<dockerfile.base.service.tag>c0d0900ec19c907d866f8360031a836049985110</dockerfile.base.service.tag>
|
||||||
<shared.resources.version>0.2.1</shared.resources.version>
|
<dockerfile.registry>dr2.rbkmoney.com</dockerfile.registry>
|
||||||
|
<shared.resources.version>0.3.6</shared.resources.version>
|
||||||
|
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -36,6 +39,11 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.rbkmoney</groupId>
|
||||||
|
<artifactId>spring-boot-starter-metrics-statsd</artifactId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||||
@ -47,7 +55,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.logstash.logback</groupId>
|
<groupId>net.logstash.logback</groupId>
|
||||||
<artifactId>logstash-logback-encoder</artifactId>
|
<artifactId>logstash-logback-encoder</artifactId>
|
||||||
<version>4.6</version>
|
<version>5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--RBK libs-->
|
<!--RBK libs-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -61,18 +74,6 @@
|
|||||||
<version>${shared.resources.version}</version>
|
<version>${shared.resources.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--Test libs-->
|
<!--Test libs-->
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.12</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-all</artifactId>
|
|
||||||
<version>1.10.19</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
@ -134,6 +135,23 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>0.8.2</version>
|
||||||
|
<configuration>
|
||||||
|
<destFile>${sonar.jacoco.reportPath}</destFile>
|
||||||
|
<append>true</append>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>agent</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
@ -7,7 +7,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan;
|
|||||||
@ServletComponentScan
|
@ServletComponentScan
|
||||||
@SpringBootApplication(scanBasePackages = {"com.rbkmoney.proxy.mocketbank.mpi"})
|
@SpringBootApplication(scanBasePackages = {"com.rbkmoney.proxy.mocketbank.mpi"})
|
||||||
public class ProxyMocketBankMpiApplication {
|
public class ProxyMocketBankMpiApplication {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(ProxyMocketBankMpiApplication.class, args);
|
SpringApplication.run(ProxyMocketBankMpiApplication.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,7 @@ import com.rbkmoney.proxy.mocketbank.mpi.utils.MpiUtils;
|
|||||||
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiCavvAlgorithm;
|
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiCavvAlgorithm;
|
||||||
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiEnrollmentStatus;
|
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiEnrollmentStatus;
|
||||||
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiTransactionStatus;
|
import com.rbkmoney.proxy.mocketbank.mpi.utils.constant.MpiTransactionStatus;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -24,13 +23,12 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/mpi")
|
@RequestMapping(value = "/mpi")
|
||||||
public class MpiController {
|
public class MpiController {
|
||||||
|
|
||||||
private final static Logger LOGGER = LoggerFactory.getLogger(MpiController.class);
|
private static final String DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||||
|
|
||||||
public final static String DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
|
||||||
|
|
||||||
@Value("${fixture.cards}")
|
@Value("${fixture.cards}")
|
||||||
private Resource fixtureCards;
|
private Resource fixtureCards;
|
||||||
@ -51,7 +49,7 @@ public class MpiController {
|
|||||||
@RequestParam(value = "year", required = true) String year,
|
@RequestParam(value = "year", required = true) String year,
|
||||||
@RequestParam(value = "month", required = true) String month
|
@RequestParam(value = "month", required = true) String month
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
LOGGER.info("VerifyEnrollment input params: pan {}, year {}, month {}",
|
log.info("VerifyEnrollment input params: pan {}, year {}, month {}",
|
||||||
MpiUtils.maskNumber(pan), year, month
|
MpiUtils.maskNumber(pan), year, month
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ public class MpiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String response = new ObjectMapper().writeValueAsString(map);
|
String response = new ObjectMapper().writeValueAsString(map);
|
||||||
LOGGER.info("VerifyEnrollment response {}", response);
|
log.info("VerifyEnrollment response {}", response);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -79,7 +77,7 @@ public class MpiController {
|
|||||||
@RequestParam(value = "paRes", required = true) String paRes
|
@RequestParam(value = "paRes", required = true) String paRes
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
|
|
||||||
LOGGER.info("ValidatePaRes input params: pan {}, paRes {}", MpiUtils.maskNumber(pan), paRes);
|
log.info("ValidatePaRes input params: pan {}, paRes {}", MpiUtils.maskNumber(pan), paRes);
|
||||||
|
|
||||||
CardUtils cardUtils = new CardUtils(cardList);
|
CardUtils cardUtils = new CardUtils(cardList);
|
||||||
Optional<Card> card = cardUtils.getCardByPan(pan);
|
Optional<Card> card = cardUtils.getCardByPan(pan);
|
||||||
@ -107,8 +105,7 @@ public class MpiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String response = new ObjectMapper().writeValueAsString(map);
|
String response = new ObjectMapper().writeValueAsString(map);
|
||||||
LOGGER.info("ValidatePaRes response {}", response);
|
log.info("ValidatePaRes response {}", response);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,15 +115,14 @@ public class MpiController {
|
|||||||
@RequestParam(value = "MD", required = true) String md,
|
@RequestParam(value = "MD", required = true) String md,
|
||||||
@RequestParam(value = "TermUrl", required = true) String termUrl
|
@RequestParam(value = "TermUrl", required = true) String termUrl
|
||||||
) {
|
) {
|
||||||
LOGGER.info("Form ACS input params: paReq {}, MD {}, TermUrl {}", paReq, md, termUrl);
|
log.info("Form ACS input params: paReq {}, MD {}, TermUrl {}", paReq, md, termUrl);
|
||||||
ModelAndView model = new ModelAndView();
|
ModelAndView model = new ModelAndView();
|
||||||
model.setViewName("acs_form");
|
model.setViewName("acs_form");
|
||||||
model.addObject("action", termUrl);
|
model.addObject("action", termUrl);
|
||||||
model.addObject("pan", "XXXX XXXX XXXX XXXX");
|
model.addObject("pan", "XXXX XXXX XXXX XXXX");
|
||||||
model.addObject("PaRes", "PaRes");
|
model.addObject("PaRes", "PaRes");
|
||||||
model.addObject("MD", md);
|
model.addObject("MD", md);
|
||||||
LOGGER.info("Form ACS show the form");
|
log.info("Form ACS show the form");
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package com.rbkmoney.proxy.mocketbank.mpi.utils;
|
package com.rbkmoney.proxy.mocketbank.mpi.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
public enum MpiAction {
|
public enum MpiAction {
|
||||||
|
|
||||||
UNKNOWN("Unknown"),
|
UNKNOWN("Unknown"),
|
||||||
@ -18,14 +23,6 @@ public enum MpiAction {
|
|||||||
|
|
||||||
private final String action;
|
private final String action;
|
||||||
|
|
||||||
MpiAction(String action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MpiAction findByValue(String value) {
|
public static MpiAction findByValue(String value) {
|
||||||
return Arrays.stream(values()).filter((action) -> action.getAction().equals(value))
|
return Arrays.stream(values()).filter((action) -> action.getAction().equals(value))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
|
@ -5,7 +5,7 @@ import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;
|
|||||||
|
|
||||||
public class MpiUtils {
|
public class MpiUtils {
|
||||||
|
|
||||||
public final static String MASK_CHAR = "*";
|
public static final String MASK_CHAR = "*";
|
||||||
|
|
||||||
public static String maskNumber(final String creditCardNumber, int startLength, int endLength, String maskChar) {
|
public static String maskNumber(final String creditCardNumber, int startLength, int endLength, String maskChar) {
|
||||||
final String cardNumber = creditCardNumber.replaceAll("\\D", "");
|
final String cardNumber = creditCardNumber.replaceAll("\\D", "");
|
||||||
|
@ -8,21 +8,21 @@ public class MpiCavvAlgorithm {
|
|||||||
/**
|
/**
|
||||||
* 0: HMAC (as per SET TransStain) (no longer in use for version 1.0.2)
|
* 0: HMAC (as per SET TransStain) (no longer in use for version 1.0.2)
|
||||||
*/
|
*/
|
||||||
public final static String HMAC_AS_PER_SET_TRANS_STAIN = "0";
|
public static final String HMAC_AS_PER_SET_TRANS_STAIN = "0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1: CVV (no longer in use for version 1.0.2).
|
* 1: CVV (no longer in use for version 1.0.2).
|
||||||
*/
|
*/
|
||||||
public final static String CVV_NO_LONGER = "1";
|
public static final String CVV_NO_LONGER = "1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2: CVV with ATN.
|
* 2: CVV with ATN.
|
||||||
*/
|
*/
|
||||||
public final static String CVV_WITH_ATN = "2";
|
public static final String CVV_WITH_ATN = "2";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 3: MasterCard SPA algorithm.
|
* 3: MasterCard SPA algorithm.
|
||||||
*/
|
*/
|
||||||
public final static String MASTERCARD_SPA_ALGORITHM = "3";
|
public static final String MASTERCARD_SPA_ALGORITHM = "3";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@ public class MpiEnrollmentStatus {
|
|||||||
* supported, or proof of attempted authentication available. The merchant uses the
|
* supported, or proof of attempted authentication available. The merchant uses the
|
||||||
* URL of issuer ACS included in VERes to create the Payer Authentication Request.
|
* URL of issuer ACS included in VERes to create the Payer Authentication Request.
|
||||||
*/
|
*/
|
||||||
public final static String AUTHENTICATION_AVAILABLE = "Y";
|
public static final String AUTHENTICATION_AVAILABLE = "Y";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cardholder Not Participating – Cardholder is not enrolled.
|
* Cardholder Not Participating – Cardholder is not enrolled.
|
||||||
*/
|
*/
|
||||||
public final static String CARDHOLDER_NOT_PARTICIPATING = "N";
|
public static final String CARDHOLDER_NOT_PARTICIPATING = "N";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unable to Authenticate or Card Not Eligible for Attempts
|
* Unable to Authenticate or Card Not Eligible for Attempts
|
||||||
* (such as a Commercial or anonymous Prepaid card).
|
* (such as a Commercial or anonymous Prepaid card).
|
||||||
*/
|
*/
|
||||||
public final static String UNABLE_TO_AUTHENTICATE = "U";
|
public static final String UNABLE_TO_AUTHENTICATE = "U";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,24 +9,24 @@ public class MpiTransactionStatus {
|
|||||||
* The merchant submits an authorization request including the
|
* The merchant submits an authorization request including the
|
||||||
* ECI and CAVV supplied in the PARes.
|
* ECI and CAVV supplied in the PARes.
|
||||||
*/
|
*/
|
||||||
public final static String AUTHENTICATION_SUCCESSFUL = "Y";
|
public static final String AUTHENTICATION_SUCCESSFUL = "Y";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The merchant must not submit a failed authentication for
|
* The merchant must not submit a failed authentication for
|
||||||
* authorization.
|
* authorization.
|
||||||
*/
|
*/
|
||||||
public final static String AUTHENTICATION_FAILED = "N";
|
public static final String AUTHENTICATION_FAILED = "N";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The merchant may process an authorization request using the
|
* The merchant may process an authorization request using the
|
||||||
* appropriate ECI.
|
* appropriate ECI.
|
||||||
*/
|
*/
|
||||||
public final static String AUTHENTICATION_COULD_NOT_BE_PERFORMED = "U";
|
public static final String AUTHENTICATION_COULD_NOT_BE_PERFORMED = "U";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The merchant submits an authorization request including the
|
* The merchant submits an authorization request including the
|
||||||
* ECI and CAVV supplied in the PARes.
|
* ECI and CAVV supplied in the PARes.
|
||||||
*/
|
*/
|
||||||
public final static String ATTEMPTS_PROCESSING_PERFORMED = "A";
|
public static final String ATTEMPTS_PROCESSING_PERFORMED = "A";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,11 @@ info:
|
|||||||
responsible: Anatoly Cherkasov
|
responsible: Anatoly Cherkasov
|
||||||
stage: dev
|
stage: dev
|
||||||
---
|
---
|
||||||
endpoints:
|
management:
|
||||||
health:
|
metrics:
|
||||||
sensitive: false
|
export:
|
||||||
|
statsd:
|
||||||
|
flavor: etsy
|
||||||
---
|
---
|
||||||
server:
|
server:
|
||||||
port: @server.port@
|
port: @server.port@
|
||||||
|
Loading…
Reference in New Issue
Block a user