diff --git a/.travis.yml b/.travis.yml index d400f0c..d2a8934 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk8 + - oraclejdk11 before_install: - chmod +x gradlew - chmod +x gradle/wrapper/gradle-wrapper.jar diff --git a/build.gradle b/build.gradle index a96ea47..81da840 100644 --- a/build.gradle +++ b/build.gradle @@ -20,13 +20,16 @@ subprojects{ apply from: "$rootDir/dependencies.gradle" apply plugin: 'kotlin' + apply plugin: 'io.spring.dependency-management' group = 'org.suggs.companydatafinder' repositories { clear() jcenter() + mavenCentral() } + dependencies { implementation libs.kotlin, @@ -40,6 +43,13 @@ subprojects{ testRuntimeOnly libs.test.junitEngine, libs.logback + + implementation ("org.springframework.boot:spring-boot-starter-web-services:${springBootVersion}") { + exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' + } + + implementation 'org.springframework.ws:spring-ws-core' + compile group: 'org.jvnet.mimepull', name: 'mimepull', version: '1.9.12' } ext { @@ -51,6 +61,7 @@ subprojects{ useJUnitPlatform() } + compileKotlin { kotlinOptions { freeCompilerArgs = ["-Xjsr305=strict"] diff --git a/company-data-finder-app/build.gradle b/company-data-finder-app/build.gradle index ce067d7..54bdc66 100644 --- a/company-data-finder-app/build.gradle +++ b/company-data-finder-app/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'org.springframework.boot' +apply plugin: 'kotlin' bootJar { archiveBaseName = 'company-data-finder-app' @@ -15,4 +16,27 @@ dependencies { testImplementation libs.test.restAssured runtime project(':company-data-finder-lib') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" +} +buildscript { + ext.kotlin_version = '1.3.72' + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} +repositories { + mavenCentral() +} +compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} +compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } } \ No newline at end of file diff --git a/company-data-finder-lib/build.gradle b/company-data-finder-lib/build.gradle index b3547bc..01f0fad 100644 --- a/company-data-finder-lib/build.gradle +++ b/company-data-finder-lib/build.gradle @@ -1,10 +1,24 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' +} jar { archiveBaseName = 'company-data-finder-lib' version = '0.0.1' } - +repositories { + mavenCentral() +} dependencies { - implementation libs.springBootStarterWeb - - testImplementation libs.snakeYaml + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } +compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} +compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + diff --git a/company-data-finder-lib/settings.gradle b/company-data-finder-lib/settings.gradle new file mode 100644 index 0000000..b699c16 --- /dev/null +++ b/company-data-finder-lib/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'company-data-finder-lib' +include ':main', + ':test' \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/CROProxy.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/CROProxy.kt new file mode 100644 index 0000000..e3d7393 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/CROProxy.kt @@ -0,0 +1,38 @@ +package org.suggs.companydatafinderlib.cro + +import org.slf4j.LoggerFactory +import org.springframework.http.client.BufferingClientHttpRequestFactory +import org.springframework.http.client.SimpleClientHttpRequestFactory +import org.springframework.web.client.RestTemplate +import org.suggs.companydatafinderlib.cro.interceptors.RequestResponseLoggingInterceptor +import org.suggs.companydatafinderlib.cro.domain.CROCompanyProfile +import org.suggs.companydatafinderlib.cro.interceptors.CROAuthInterceptor + +class CROProxy(private val authUsername: String) { + + private val restTemplate = createRestTemplateWithInterceptorsForAuthentication() + private val log = LoggerFactory.getLogger(this::class.java) + + private fun createRestTemplateWithInterceptorsForAuthentication(): RestTemplate { + val factory = BufferingClientHttpRequestFactory(SimpleClientHttpRequestFactory()) + val template = RestTemplate(factory) + template.interceptors = listOf( + CROAuthInterceptor(authUsername), + RequestResponseLoggingInterceptor()) + return template + } + + /** + * Retrieves company profile data for a given cro company id + */ + fun getCompanyDataFor(companyId: String): List { + log.debug("Retrieving company profile data for company id $companyId") + val url = "https://services.cro.ie/cws/companies?company_num=$companyId" + return when (val profile = restTemplate.getForEntity(url, Array::class.java).body) { + null -> throw IllegalStateException("Could not create company profile for company number $companyId") + else -> profile.asList() + } + } + + +} \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/README.md b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/README.md new file mode 100644 index 0000000..fb708f5 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/README.md @@ -0,0 +1,4 @@ +# CRO API +Use this API for accessing data and documents from CRO (Irish registrar of companies). +See the tests for details on how to use the api and simplified api access. +API access is directly to CRO. Details for connection etc can be found at the [CRO API](https://services.cro.ie/companies.aspx) pages. diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyProfile.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyProfile.kt new file mode 100644 index 0000000..4e429bb --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyProfile.kt @@ -0,0 +1,17 @@ +package org.suggs.companydatafinderlib.cro.domain + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.* + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class CROCompanyProfile(@JsonProperty("company_num") val croNumber: String, + @JsonProperty("company_name") val croBusinessName: String, + @JsonProperty("company_addr_1") val croAddress1: String, + @JsonProperty("company_addr_2") val croAddress2: String, + @JsonProperty("company_addr_3") val croAddress3: String, + @JsonProperty("company_addr_4") val croAddress4: String, + @JsonProperty("company_reg_date") val croRegisteredDate: Date) diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/CROAuthInterceptor.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/CROAuthInterceptor.kt new file mode 100644 index 0000000..c0aa1e7 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/CROAuthInterceptor.kt @@ -0,0 +1,16 @@ +package org.suggs.companydatafinderlib.cro.interceptors + +import org.springframework.http.HttpRequest +import org.springframework.http.client.ClientHttpRequestExecution +import org.springframework.http.client.ClientHttpRequestInterceptor +import org.springframework.http.client.ClientHttpResponse +import java.util.* + +class CROAuthInterceptor(private val username: String) : ClientHttpRequestInterceptor { + override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse { + val auth = "$username" + val encodedAuth = Base64.getEncoder().encodeToString(auth.toByteArray()) + request.headers.add("Authorization", "Basic $encodedAuth") + return execution.execute(request, body) + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/RequestResponseLoggingInterceptor.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/RequestResponseLoggingInterceptor.kt new file mode 100644 index 0000000..89835f7 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/cro/interceptors/RequestResponseLoggingInterceptor.kt @@ -0,0 +1,53 @@ +package org.suggs.companydatafinderlib.cro.interceptors + +import org.slf4j.LoggerFactory +import org.springframework.http.HttpRequest +import org.springframework.http.MediaType +import org.springframework.http.client.ClientHttpRequestExecution +import org.springframework.http.client.ClientHttpRequestInterceptor +import org.springframework.http.client.ClientHttpResponse +import org.springframework.util.StreamUtils +import java.io.IOException +import java.nio.charset.Charset + +class RequestResponseLoggingInterceptor : ClientHttpRequestInterceptor { + + private val log = LoggerFactory.getLogger(this::class.java) + + override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse { + logRequest(request, body) + val response = execution.execute(request, body) + logResponse(response) + return response + } + + @Throws(IOException::class) + private fun logRequest(request: HttpRequest, body: ByteArray) { + if (log.isDebugEnabled) { + log.debug("===========================request begin================================================") + log.debug("URI : ${request.uri}") + log.debug("Method : ${request.method}") + log.debug("Headers : ${request.headers}") + log.debug("Request body: ${String(body, Charset.forName("UTF-8"))}") + log.debug("==========================request end================================================") + } + } + + @Throws(IOException::class) + private fun logResponse(response: ClientHttpResponse) { + if (log.isDebugEnabled) { + log.debug("============================response begin==========================================") + log.debug("Status code : ${response.statusCode}") + log.debug("Status text : ${response.statusText}") + log.debug("Headers : ${response.headers}") + if (response.headers.contentType!!.compareTo(MediaType.APPLICATION_JSON) == 0) { + log.debug("Response body: ${StreamUtils.copyToString(response.body, Charset.defaultCharset())}") + } else { + //log.debug("Response body: {huge blob of data}") + log.debug("Response body: ${StreamUtils.copyToString(response.body, Charset.defaultCharset())}") + } + log.debug("=======================response end=================================================") + } + } + +} \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/KVKProxy.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/KVKProxy.kt new file mode 100644 index 0000000..10ca6fb --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/KVKProxy.kt @@ -0,0 +1,38 @@ +package org.suggs.companydatafinderlib.kvk + +import org.slf4j.LoggerFactory +import org.springframework.http.client.BufferingClientHttpRequestFactory +import org.springframework.http.client.SimpleClientHttpRequestFactory +import org.springframework.web.client.RestTemplate +import org.suggs.companydatafinderlib.cro.interceptors.RequestResponseLoggingInterceptor +import org.suggs.companydatafinderlib.kvk.domain.KVKCompanyProfile +import org.suggs.companydatafinderlib.kvk.interceptors.KVKAuthInterceptor + +class KVKProxy(private val authUsername: String, private val authPassword: String) { + + private val restTemplate = createRestTemplateWithInterceptorsForAuthentication() + private val log = LoggerFactory.getLogger(this::class.java) + + private fun createRestTemplateWithInterceptorsForAuthentication(): RestTemplate { + val factory = BufferingClientHttpRequestFactory(SimpleClientHttpRequestFactory()) + val template = RestTemplate(factory) + template.interceptors = listOf( + RequestResponseLoggingInterceptor(), + KVKAuthInterceptor(authUsername, authPassword)) + return template + } + + /** + * Retrieves company profile data for a given kvk company id + */ + fun getCompanyDataFor(companyId: String): KVKCompanyProfile { + log.debug("Retrieving company profile data for company id $companyId") + val url = "https://api.kvk.nl:443/api/v2/testprofile/companies?kvkNumber=$companyId" + return when (val profile = restTemplate.getForObject(url, KVKCompanyProfile::class.java)) { + null -> throw IllegalStateException("Could not create company profile for company number $companyId") + else -> profile + } + } + + +} \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/README.md b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/README.md new file mode 100644 index 0000000..bdcb067 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/README.md @@ -0,0 +1,4 @@ +# KVK API +Use this API for accessing data and documents from KVK (Dutch registered companies). +See the tests for details on how to use the api and simplified api access. +API access is directly to KVK. Details for connection etc can be found at the [KVK API](https://developers.kvk.nl/documentation/search-v2-test) pages. diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyProfile.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyProfile.kt new file mode 100644 index 0000000..7952851 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyProfile.kt @@ -0,0 +1,38 @@ +package org.suggs.companydatafinderlib.kvk.domain + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.* + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class KVKCompanyProfile(@JsonProperty("data") val kvkData: KVKData) + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class KVKData(@JsonProperty("items") val kvkDataItems: List) + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class KVKDataItem(@JsonProperty("kvkNumber") val kvkNumber: String, + @JsonProperty("tradeNames") val kvkTradeNames: KVKTradeNames, + @JsonProperty("addresses") val kvkAddresses: List, + @JsonProperty("foundationDate") val kvkFoundationDate: Date) + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class KVKTradeNames(@JsonProperty("businessName") val kvkBusinessName: String, + @JsonProperty("currentTradeNames") val kvkTradeNames: List) + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class KVKAddress(@JsonProperty("street") val kvkStreetAddress: String, + @JsonProperty("houseNumber") val kvkHouseNumber: String, + @JsonProperty("postalCode") val kvkPostCode: String, + @JsonProperty("city") val kvkCity: String, + @JsonProperty("country") val kvkCountry: String) \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/KVKAuthInterceptor.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/KVKAuthInterceptor.kt new file mode 100644 index 0000000..dd40827 --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/KVKAuthInterceptor.kt @@ -0,0 +1,16 @@ +package org.suggs.companydatafinderlib.kvk.interceptors + +import org.springframework.http.HttpRequest +import org.springframework.http.client.ClientHttpRequestExecution +import org.springframework.http.client.ClientHttpRequestInterceptor +import org.springframework.http.client.ClientHttpResponse +import java.util.* + +class KVKAuthInterceptor(private val username: String, private val password: String) : ClientHttpRequestInterceptor { + override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse { + val auth = "$username:$password" + val encodedAuth = Base64.getEncoder().encodeToString(auth.toByteArray()) + request.headers.add("Authorization", "Basic $encodedAuth") + return execution.execute(request, body) + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/RequestResponseLoggingInterceptor.kt b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/RequestResponseLoggingInterceptor.kt new file mode 100644 index 0000000..86cd14b --- /dev/null +++ b/company-data-finder-lib/src/main/kotlin/org/suggs/companydatafinderlib/kvk/interceptors/RequestResponseLoggingInterceptor.kt @@ -0,0 +1,53 @@ +package org.suggs.companydatafinderlib.kvk.interceptors + +import org.slf4j.LoggerFactory +import org.springframework.http.HttpRequest +import org.springframework.http.MediaType +import org.springframework.http.client.ClientHttpRequestExecution +import org.springframework.http.client.ClientHttpRequestInterceptor +import org.springframework.http.client.ClientHttpResponse +import org.springframework.util.StreamUtils +import java.io.IOException +import java.nio.charset.Charset + +class RequestResponseLoggingInterceptor : ClientHttpRequestInterceptor { + + private val log = LoggerFactory.getLogger(this::class.java) + + override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse { + logRequest(request, body) + val response = execution.execute(request, body) + logResponse(response) + return response + } + + @Throws(IOException::class) + private fun logRequest(request: HttpRequest, body: ByteArray) { + if (log.isDebugEnabled) { + log.debug("===========================request begin================================================") + log.debug("URI : ${request.uri}") + log.debug("Method : ${request.method}") + log.debug("Headers : ${request.headers}") + log.debug("Request body: ${String(body, Charset.forName("UTF-8"))}") + log.debug("==========================request end================================================") + } + } + + @Throws(IOException::class) + private fun logResponse(response: ClientHttpResponse) { + if (log.isDebugEnabled) { + log.debug("============================response begin==========================================") + log.debug("Status code : ${response.statusCode}") + log.debug("Status text : ${response.statusText}") + log.debug("Headers : ${response.headers}") + if (response.headers.contentType!!.compareTo(MediaType.APPLICATION_JSON) == 0) { + log.debug("Response body: ${StreamUtils.copyToString(response.body, Charset.defaultCharset())}") + } else { + //log.debug("Response body: {huge blob of data}") + log.debug("Response body: ${StreamUtils.copyToString(response.body, Charset.defaultCharset())}") + } + log.debug("=======================response end=================================================") + } + } + +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/build.gradle b/company-data-finder-lib/src/test/build.gradle new file mode 100644 index 0000000..bdc5dd9 --- /dev/null +++ b/company-data-finder-lib/src/test/build.gradle @@ -0,0 +1,3 @@ +dependencies { + compile project(':main') +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/CompaniesHouseTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/CompaniesHouseTest.kt index 3c79633..ccb2996 100644 --- a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/CompaniesHouseTest.kt +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/CompaniesHouseTest.kt @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test import org.slf4j.LoggerFactory import org.yaml.snakeyaml.Yaml + @DisplayName("Companies House Proxy allows us to") class CompaniesHouseTest { diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/domain/CompaniesHouseCompanyDataParseTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/domain/CompaniesHouseCompanyDataParseTest.kt index 2dcc28c..2edb725 100644 --- a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/domain/CompaniesHouseCompanyDataParseTest.kt +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/companieshouse/domain/CompaniesHouseCompanyDataParseTest.kt @@ -9,6 +9,7 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.junit.jupiter.api.function.Executable import org.slf4j.LoggerFactory +import org.suggs.companydatafinderlib.companieshouse.domain.CompaniesHouseCompanyProfile @DisplayName("Companies House Response contains company data directly from CH") class CompaniesHouseCompanyDataParseTest { diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/CROTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/CROTest.kt new file mode 100644 index 0000000..3b71f44 --- /dev/null +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/CROTest.kt @@ -0,0 +1,34 @@ +package org.suggs.companydatafinderlib.cro + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.slf4j.LoggerFactory +import org.yaml.snakeyaml.Yaml + +@DisplayName("CRO Proxy allows us to") +class CROTest { + + private val log = LoggerFactory.getLogger(this::class.java) + private val config = loadConfig() + private var cRO = CROProxy(config.get("cro_key")) + + @Test fun `retrieve data using cro ID`() { + val companyData = cRO.getCompanyDataFor("83740") + log.debug("CRO Data: $companyData") + assertThat(companyData).isNotNull + } + + private fun loadConfig(): AppConfig { + return AppConfig(Yaml().load(this.javaClass.classLoader.getResourceAsStream("application.yml"))) + } +} + +data class AppConfig(val configData: Map) { + fun get(key: String): String { + return when (val data = configData[key]) { + null -> throw IllegalStateException("Could not locate configuration data for key: $key") + else -> data + } + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyDataParseTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyDataParseTest.kt new file mode 100644 index 0000000..08fc090 --- /dev/null +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/cro/domain/CROCompanyDataParseTest.kt @@ -0,0 +1,49 @@ +package org.suggs.companydatafinderlib.cro.domain + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.KotlinModule +import com.fasterxml.jackson.module.kotlin.readValue +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertAll +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.function.Executable +import org.slf4j.LoggerFactory + +@DisplayName("CRO Response contains company data directly from CRO") +class CROCompanyDataParseTest { + + private val JSON = """[ + {"company_num":83740, + "company_bus_ind":"C", + "company_name":"FOSTER WHEELER IRELAND LIMITED", + "company_addr_1":"C\/O, COOPERS, LYBRAND,", + "company_addr_2":"FITZWILTON HOUSE,", + "company_addr_3":"WILTON PLACE,", + "company_addr_4":"DUBLIN 2.", + "company_reg_date":"1981-07-08T00:00:00Z", + "company_status_desc":"Dissolved", + "company_status_date":"1993-11-19T00:00:00Z", + "last_ar_date":"0001-01-01T00:00:00Z", + "next_ar_date":"0001-01-01T00:00:00Z", + "last_acc_date":"0001-01-01T00:00:00Z", + "comp_type_desc":"Private limited by shares", + "company_type_code":19, + "company_status_code":8, + "place_of_business":"", + "eircode":""} + ]""".trimMargin() + + private val mapper = ObjectMapper().registerModule(KotlinModule()) + private val log = LoggerFactory.getLogger(this::class.java) + + @Test + fun `can create cro response from JSON`() { + val responseList: List = mapper.readValue(JSON) + log.debug(responseList[0].croNumber) + assertAll( + Executable { assertThat(responseList[0].croBusinessName).isNotNull() }, + Executable { assertThat(responseList[0].croNumber).isEqualTo("83740") } + ) + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/KVKTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/KVKTest.kt new file mode 100644 index 0000000..1213545 --- /dev/null +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/KVKTest.kt @@ -0,0 +1,35 @@ +package org.suggs.companydatafinderlib.kvk + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.slf4j.LoggerFactory +import org.suggs.companydatafinderlib.cro.AppConfig +import org.yaml.snakeyaml.Yaml + +@DisplayName("KVK Proxy allows us to") +class KVKTest { + + private val log = LoggerFactory.getLogger(this::class.java) + private val config = loadConfig() + private var kVK = KVKProxy(config.get("user"), config.get("pass")) + + @Test fun `retrieve data using kvk ID`() { + val companyData = kVK.getCompanyDataFor("69599084") + log.debug("KVK Data: $companyData") + assertThat(companyData).isNotNull + } + + private fun loadConfig(): AppConfig { + return AppConfig(Yaml().load(this.javaClass.classLoader.getResourceAsStream("application.yml"))) + } +} + +data class AppConfig(val configData: Map) { + fun get(key: String): String { + return when (val data = configData[key]) { + null -> throw IllegalStateException("Could not locate configuration data for key: $key") + else -> data + } + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyDataParseTest.kt b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyDataParseTest.kt new file mode 100644 index 0000000..03a474f --- /dev/null +++ b/company-data-finder-lib/src/test/kotlin/org/suggs/companydatafinderlib/kvk/domain/KVKCompanyDataParseTest.kt @@ -0,0 +1,91 @@ +package org.suggs.companydatafinderlib.kvk.domain + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.KotlinModule +import com.fasterxml.jackson.module.kotlin.readValue +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertAll +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.function.Executable +import org.slf4j.LoggerFactory + +@DisplayName("KVK Response contains company data directly from KVK") +class KVKCompanyDataParseTest { + + private val JSON = """{ + |"apiVersion": "2.0", + |"meta":{}, + |"data":{ + |"itemsPerPage": 1, + |"startPage": 1, + |"totalItems": 2, + |"nextLink": "https://api.kvk.nl/api/v2/profile/companies?kvkNumber=69599084&startPage=2", + |"items": [{ + |"kvkNumber": "69599084", + |"branchNumber": "000038509504", + |"tradeNames":{ + |"businessName": "Test EMZ Dagobert", + |"currentTradeNames": [ "Test EMZ Dagobert", + |"Tweede handelsnaam 1MZ", + |"Derde handelsnaam 1MZ", + |"Vierde handelsnaam 1MZ"] + |}, + |"legalForm": "Eenmanszaak", + |"businessActivities": [{ + |"sbiCode": "1011", + |"sbiCodeDescription": "Slachterijen (geen pluimvee-)", + |"isMainSbi": true},{ + |"sbiCode": "1012", + |"sbiCodeDescription": "Pluimveeslachterijen", + |"isMainSbi": false},{ + |"sbiCode": "1013", + |"sbiCodeDescription": "Vleesverwerking (niet tot maaltijden)", + |"isMainSbi": false}], + |"hasEntryInBusinessRegister": true, + |"hasCommercialActivities": true, + |"hasNonMailingIndication": true, + |"isLegalPerson": false, + |"isBranch": true, + |"isMainBranch": true, + |"employees": 1, + |"foundationDate": "20170108", + |"registrationDate": "20170710", + |"addresses": [{ + |"type": "vestigingsadres", + |"bagId": "0363010000951555", + |"street": "Abebe Bikilalaan", + |"houseNumber": "17", + |"houseNumberAddition": "", + |"postalCode": "1034WL", + |"city": "Amsterdam", + |"country": "Nederland", + |"gpsLatitude": 52.403176952488096, + |"gpsLongitude": 4.917604057883805, + |"rijksdriehoekX": 123042, + |"rijksdriehoekY": 490697, + |"rijksdriehoekZ": 0 + |} + |] + |} + |] + |} +|} +""".trimMargin() + + private val mapper = ObjectMapper().registerModule(KotlinModule()) + private val log = LoggerFactory.getLogger(this::class.java) + + @Test + fun `can create kvk response from JSON`() { + val response = mapper.readValue(JSON) + log.debug(response.toString()) + assertAll( + Executable { assertThat(response.kvkData.kvkDataItems[0].kvkTradeNames.kvkBusinessName).isNotNull() }, + Executable { assertThat(response.kvkData.kvkDataItems[0].kvkNumber).isEqualTo("69599084") }, + Executable { assertThat(response.kvkData.kvkDataItems[0].kvkFoundationDate).isNotNull() }, + Executable { assertThat(response.kvkData.kvkDataItems[0].kvkAddresses[0].kvkStreetAddress).isNotNull() } + + ) + } +} \ No newline at end of file diff --git a/company-data-finder-lib/src/test/resources/application.yml b/company-data-finder-lib/src/test/resources/application.yml index d39b023..2f8418b 100644 --- a/company-data-finder-lib/src/test/resources/application.yml +++ b/company-data-finder-lib/src/test/resources/application.yml @@ -1 +1,8 @@ -auth: "_JMZGS85jZjkf5sAQsM8ESbFdzo9sEyUqnnQIXmM" \ No newline at end of file +auth: "_JMZGS85jZjkf5sAQsM8ESbFdzo9sEyUqnnQIXmM" +user: "testourapis" +pass: "testourapis" +cro_user: "test@cro.ie" +cro_pass: "da093a04-c9d7-46d7-9c83-9c9f8630d5e0" +cro_key: "test@cro.ie:da093a04-c9d7-46d7-9c83-9c9f8630d5e0" +cro_key1: "dGVzdEBjcm8uaWU6ZGEwOTNhMDQtYzlkNy00NmQ3LTljODMtOWM5Zjg2MzBkNWUw" +cro_key2: "dGVzdEBjcm8uaWU6ZGEwOTNhMDQtYzlkNy00NmQ3LTljODMtOWM5Zjg2MzBkNWUwOg" \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index be7cace..fda4db2 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,7 +1,8 @@ ext { kotlinVersion = '1.3.41' - + springBootVersion = '2.1.7.RELEASE' + libs = [ kotlin : "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", @@ -29,6 +30,7 @@ ext { restAssured : 'io.rest-assured:rest-assured:3.3.0', springBootStarterTest: "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + ] ] } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ef9a9e0..ea7627b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Mon Dec 23 13:10:46 GMT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-all.zip