Commit fa37361a authored by Gana Samantula's avatar Gana Samantula

Merge branch 'repo-migration' into 'master'

Migrated to new git repo in payments group

See merge request !1
parents 9cb0d819 68981ca9
#Wed Sep 01 13:59:58 EDT 2021
gradle.version=7.1.1
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
azure-data-service-demo
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AzureSettings">
<option name="appInsights" value="rO0ABXVyAEtbTGNvbS5taWNyb3NvZnQuYXBwbGljYXRpb25pbnNpZ2h0cy5wcmVmZXJlbmNlLkFwcGxpY2F0aW9uSW5zaWdodHNSZXNvdXJjZTvCzxEP0C2HbAIAAHhwAAAAAA==" />
</component>
</project>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Gradle Imported" enabled="true">
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.20/18bcea7d5df4d49227b4a0743a536208ce4825bb/lombok-1.18.20.jar" />
</processorPath>
<module name="azure-data-service-demo.main" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="/usr/local/Cellar/gradle/7.0.2_2/libexec" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="corretto-11" project-jdk-type="JavaSDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
# Read Me First
The following was discovered as part of building this project:
* The original package name 'com.nisum.azure-data-service-demo' is invalid and this project uses 'com.nisum.azuredataservicedemo' instead.
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Gradle documentation](https://docs.gradle.org)
* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.4/gradle-plugin/reference/html/)
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.4/gradle-plugin/reference/html/#build-image)
* [Azure Support](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/spring)
### Guides
The following guides illustrate how to use some features concretely:
* [Deploying a Spring Boot app to Azure](https://spring.io/guides/gs/spring-boot-for-azure/)
### Additional Links
These additional references should also help you:
* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)
plugins {
id 'org.springframework.boot' version '2.5.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.nisum'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('azureVersion', "3.6.1")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'com.azure.spring:azure-spring-boot-starter'
implementation 'com.azure:azure-spring-data-cosmos:3.9.0'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
compileOnly "io.springfox:springfox-swagger-ui:3.0.0"
}
dependencyManagement {
imports {
mavenBom "com.azure.spring:azure-spring-boot-bom:${azureVersion}"
}
}
test {
useJUnitPlatform()
}
{
"properties": [
{
"name": "azure.cosmos.queryMetricsEnabled",
"type": "java.lang.Boolean",
"description": "Description for azure.cosmos.queryMetricsEnabled."
}
] }
\ No newline at end of file
azure:
cosmos:
# Insert uri, key and secondaryKey here
uri: https://fe8c3a75-0ee0-4-231-b9ee.documents.azure.com:443/
key: Uz29aJHvkznxCWplKVU1ljCfW8ux71twt0jZaQ5PuJYmkEbRU3m6lLH8QONimGQnLFnlP4lZ8SwniJrrWjvYyg
secondaryKey: UmIsFvsFgG2CNHLsf845asWRt8C4dlClL783jwlnVqzsTD59FxWj5YStmggBVPMQsggDo2n9hkYAe8IPAIDZsQ==
database: payment-authorizations
queryMetricsEnabled: true
server:
port: 8081
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
rootProject.name = 'azure-data-service-demo'
package com.nisum.paymentgatewayazuredataservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AzureDataServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AzureDataServiceDemoApplication.class, args);
}
}
package com.nisum.paymentgatewayazuredataservice.configutation;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.DirectConnectionConfig;
import com.azure.cosmos.GatewayConnectionConfig;
import com.azure.spring.data.cosmos.config.AbstractCosmosConfiguration;
import com.azure.spring.data.cosmos.config.CosmosConfig;
import com.azure.spring.data.cosmos.core.ResponseDiagnostics;
import com.azure.spring.data.cosmos.core.ResponseDiagnosticsProcessor;
import com.azure.spring.data.cosmos.repository.config.EnableCosmosRepositories;
import io.micrometer.core.lang.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCosmosRepositories
public class CosmosConfiguration extends AbstractCosmosConfiguration {
private static final Logger logger = LoggerFactory.getLogger(CosmosConfiguration.class);
@Value("${azure.cosmos.uri}")
private String uri;
@Value("${azure.cosmos.key}")
private String key;
@Value("${azure.cosmos.secondaryKey}")
private String secondaryKey;
@Value("${azure.cosmos.database}")
private String dbName;
@Value("${azure.cosmos.queryMetricsEnabled}")
private Boolean queryMetricsEnabled;
private AzureKeyCredential azureKeyCredential;
private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
@Override
public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
logger.info("Response Diagnostics {}", responseDiagnostics);
}
}
@Bean
public CosmosClientBuilder getCosmosClientBuilder() {
this.azureKeyCredential = new AzureKeyCredential(key);
DirectConnectionConfig directConnectionConfig = new DirectConnectionConfig();
GatewayConnectionConfig gatewayConnectionConfig = new GatewayConnectionConfig();
return new CosmosClientBuilder()
.endpoint(uri)
.credential(azureKeyCredential)
.directMode(directConnectionConfig, gatewayConnectionConfig);
}
public CosmosConfig cosmosConfig() {
return CosmosConfig.builder()
.enableQueryMetrics(queryMetricsEnabled)
.responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
.build();
}
public void switchToSecondaryKey() {
this.azureKeyCredential.update(secondaryKey);
}
@Override
protected String getDatabaseName() {
return dbName;
}
}
package com.nisum.paymentgatewayazuredataservice.controller;
import com.nisum.paymentgatewayazuredataservice.domain.model.PaymentAuthData;
import com.nisum.paymentgatewayazuredataservice.service.PaymentAuthService;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("api/authorizations")
public class PaymentAuthController {
private final PaymentAuthService service;
public PaymentAuthController(PaymentAuthService service) {
this.service = service;
}
@PostMapping("")
public Mono<PaymentAuthData> createAuthorization(@RequestBody PaymentAuthData data) {
return service.create(data);
}
@GetMapping("{id}")
public Mono<PaymentAuthData> getAuthorization(@PathVariable("id") String id) {
return service.getOneById(id);
}
}
package com.nisum.paymentgatewayazuredataservice.domain.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CreditCardAdditionalData {
private String avsResult;
private String cardSummary;
private String refusalReasonRaw;
private String eci;
private String acquirerAccountCode;
private String expiryDate;
private String xid;
private String cavvAlgorithm;
private String cardBin;
private String threeDAuthenticated;
private String cvcResultRaw;
private String paymentMethodVariant;
private String acquirerReference;
private String cardIssuingCountry;
private String liabilityShift;
private String authCode;
private String cardHolderName;
private String isCardCommercial;
private String threeDOffered;
private String threeDOfferedResponse;
private String authorisationMid;
private String issuerCountry;
private String cvcResult;
private String cavv;
private String threeDAuthenticatedResponse;
private String avsResultRaw;
private String paymentMethod;
private String cardPaymentMethod;
private String acquirerCode;
}
package com.nisum.paymentgatewayazuredataservice.domain.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CreditCardAuthorizeResponse {
CreditCardAdditionalData additionalData;
private String resultCode;
private String authCode;
private String pspReference;
}
package com.nisum.paymentgatewayazuredataservice.domain.model;
import com.azure.spring.data.cosmos.core.mapping.Container;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;
@Container(containerName = "PaymentAuthContainer", ru = "400")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class PaymentAuthData {
@Id
private String id;
private String cardNumber;
private String cvv;
private String address;
private Number amount;
private CreditCardAuthorizeResponse creditCardAuthorizeResponse;
}
package com.nisum.paymentgatewayazuredataservice.repository;
import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
import com.nisum.paymentgatewayazuredataservice.domain.model.PaymentAuthData;
import org.springframework.stereotype.Repository;
@Repository
public interface PaymentAuthRepository extends ReactiveCosmosRepository<PaymentAuthData, String> {
}
package com.nisum.paymentgatewayazuredataservice.service;
import com.nisum.paymentgatewayazuredataservice.domain.model.PaymentAuthData;
import com.nisum.paymentgatewayazuredataservice.repository.PaymentAuthRepository;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.UUID;
@Service
public class PaymentAuthService {
private PaymentAuthRepository repository;
public PaymentAuthService(PaymentAuthRepository repository) {
this.repository = repository;
}
public Mono<PaymentAuthData> getOneById(String id) {
return repository.findById(id)
.onErrorResume(Mono::error);
}
public Mono<PaymentAuthData> create(PaymentAuthData data) {
data.setId(UUID.randomUUID().toString());
return repository.save(data);
}
}
{
"properties": [
{
"name": "azure.cosmos.queryMetricsEnabled",
"type": "java.lang.Boolean",
"description": "Description for azure.cosmos.queryMetricsEnabled."
}
] }
\ No newline at end of file
azure:
cosmos:
# Insert uri, key and secondaryKey here
database: payment-authorizations
queryMetricsEnabled: true
server:
port: 8081
package com.nisum.paymentgatewayazuredataservice;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AzureDataServiceDemoApplicationTests {
@Test
void contextLoads() {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment