diff --git a/build.gradle b/build.gradle index a32b42e..d8aaad8 100644 --- a/build.gradle +++ b/build.gradle @@ -34,7 +34,7 @@ dependencies { implementation 'org.mapstruct:mapstruct:1.5.5.Final' implementation 'commons-validator:commons-validator:1.7' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '4.0.1' - + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.2' implementation group: 'com.google.cloud', name: 'google-cloud-vision', version: '3.55.0' implementation group: 'com.google.api-client', name: 'google-api-client', version: '2.7.2' diff --git a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java index 933ee69..f4465ef 100644 --- a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java @@ -23,7 +23,8 @@ public class HandlerConfig { CompanyHandler companyHandler, TariffHandler tariffHandler, TariffInfoHandler tariffInfoHandler, - ReferralHandler referralHandler + ReferralHandler referralHandler, + DaDataHandler daDataHandler ) { Map map = new HashMap<>(); map.put(20001, login); @@ -38,6 +39,7 @@ public class HandlerConfig { map.put(30001, tariffHandler); map.put(30002, tariffInfoHandler); map.put(30003, referralHandler); + map.put(30004, daDataHandler); return map; } diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataAddress.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataAddress.java new file mode 100644 index 0000000..600783b --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataAddress.java @@ -0,0 +1,10 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DaDataAddress { + private String value; +} diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataData.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataData.java new file mode 100644 index 0000000..983bba9 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataData.java @@ -0,0 +1,11 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DaDataData { + private String inn; + private DaDataAddress address; +} diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataRequest.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataRequest.java new file mode 100644 index 0000000..6fd406e --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataRequest.java @@ -0,0 +1,11 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class DaDataRequest { + + @JsonProperty("inn") + private String inn; +} diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataResponse.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataResponse.java new file mode 100644 index 0000000..f95c1cf --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataResponse.java @@ -0,0 +1,16 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class DaDataResponse { + @JsonProperty("companyName") + private String companyName; + + @JsonProperty("inn") + private String inn; + + @JsonProperty("address") + private String address; +} diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataSuggestion.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataSuggestion.java new file mode 100644 index 0000000..4b32c8b --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataSuggestion.java @@ -0,0 +1,11 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DaDataSuggestion { + private String value; + private DaDataData data; +} \ No newline at end of file diff --git a/src/main/java/ru/soune/nocopy/dto/dadata/DaDataWrapper.java b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataWrapper.java new file mode 100644 index 0000000..2807c3e --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/dadata/DaDataWrapper.java @@ -0,0 +1,12 @@ +package ru.soune.nocopy.dto.dadata; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.List; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DaDataWrapper { + private List suggestions; +} diff --git a/src/main/java/ru/soune/nocopy/handler/DaDataHandler.java b/src/main/java/ru/soune/nocopy/handler/DaDataHandler.java new file mode 100644 index 0000000..7d358b1 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/handler/DaDataHandler.java @@ -0,0 +1,32 @@ +package ru.soune.nocopy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.soune.nocopy.dto.BaseRequest; +import ru.soune.nocopy.dto.BaseResponse; +import ru.soune.nocopy.dto.MessageCode; +import ru.soune.nocopy.dto.dadata.DaDataRequest; +import ru.soune.nocopy.dto.dadata.DaDataResponse; +import ru.soune.nocopy.service.dadata.DaDataService; + +@Component +@RequiredArgsConstructor +@Slf4j +public class DaDataHandler implements RequestHandler { + + private final DaDataService daDataService; + + private ObjectMapper mapper = new ObjectMapper(); + + @Override + public BaseResponse handle(BaseRequest request) throws Exception { + DaDataRequest daDataRequest = mapper.convertValue(request.getMessageBody(), DaDataRequest.class); + String inn = daDataRequest.getInn(); + DaDataResponse daData = daDataService.callDaData(inn); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), daData); + } +} diff --git a/src/main/java/ru/soune/nocopy/service/dadata/DaDataService.java b/src/main/java/ru/soune/nocopy/service/dadata/DaDataService.java new file mode 100644 index 0000000..a1a6113 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/service/dadata/DaDataService.java @@ -0,0 +1,83 @@ +package ru.soune.nocopy.service.dadata; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import ru.soune.nocopy.dto.dadata.DaDataResponse; +import ru.soune.nocopy.dto.dadata.DaDataSuggestion; +import ru.soune.nocopy.dto.dadata.DaDataWrapper; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DaDataService { + + @Value("${dadata.api-key}") + private String apiKey ; + + @Value("${dadata.url}") + private String url ; + + private final OkHttpClient httpClient; + + public DaDataService() { + this.httpClient = new OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .writeTimeout(5, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .callTimeout(20, TimeUnit.SECONDS) + .retryOnConnectionFailure(true) + .build(); + } + + public DaDataResponse callDaData(String inn) throws IOException { + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException("SearchAPI key not configured"); + } + + String jsonBody = String.format("{\"query\": \"%s\"}", inn); + + Request request = new Request.Builder() + .url("https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party") + .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody)) + .header("Accept", "application/json") + .header("Authorization", "Token " + apiKey) + .build(); + + try (Response response = httpClient.newCall(request).execute()) { + ResponseBody body = response.body(); + if (body == null) { + throw new IOException("Empty response body"); + } + + String jsonResponse = body.string(); + + ObjectMapper mapper = new ObjectMapper(); + DaDataWrapper wrapper = mapper.readValue(jsonResponse, DaDataWrapper.class); + + DaDataResponse daDataResponse = new DaDataResponse(); + + if (wrapper.getSuggestions() != null && !wrapper.getSuggestions().isEmpty()) { + DaDataSuggestion suggestion = wrapper.getSuggestions().get(0); + + daDataResponse.setCompanyName(suggestion.getValue()); + + if (suggestion.getData() != null) { + daDataResponse.setInn(suggestion.getData().getInn()); + + if (suggestion.getData().getAddress() != null) { + daDataResponse.setAddress(suggestion.getData().getAddress().getValue()); + } + } + } + + return daDataResponse; + } + } +} diff --git a/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java b/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java index 1b219a8..ba6fa2c 100644 --- a/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java +++ b/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java @@ -155,7 +155,7 @@ public class SearchImageService { JsonNode imageNode = match.path("image"); if (!imageNode.isMissingNode()) { - String directUrl = imageNode.path("link").asText(null); + String directUrl = imageNode.path("link").asText(); if (directUrl != null && !directUrl.isBlank()) { result.setUrl(directUrl); } @@ -245,15 +245,15 @@ public class SearchImageService { JsonNode imageNode = match.path("image"); if (imageNode.isObject()) { - result.setUrl(imageNode.path("link").asText(null)); + result.setUrl(imageNode.path("link").asText()); result.setWidth(imageNode.path("width").asInt(0)); result.setHeight(imageNode.path("height").asInt(0)); } - result.setPageUrl(match.path("link").asText(null)); - result.setPageTitle(match.path("title").asText(null)); + result.setPageUrl(match.path("link").asText()); + result.setPageTitle(match.path("title").asText()); - String source = match.path("source").asText(null); + String source = match.path("source").asText(); result.setHost(extractHostFromSource(source)); return result; diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 13f2f11..e5abeb3 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -51,6 +51,10 @@ spring: enabled: true resolve-lazily: false +dadata: + api-key: 0109fcc9d5a0a68c08f3b12ba7e2a620ea438ef7 + url: "https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party" + file: storage: base-path: ${FILE_STORAGE_PATH:/data/uploads}