diff --git a/parsing-service/build.gradle b/parsing-service/build.gradle index e056776..b943a30 100644 --- a/parsing-service/build.gradle +++ b/parsing-service/build.gradle @@ -50,6 +50,9 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'org.springframework.boot:spring-boot-starter-webflux' + + implementation 'org.springframework.retry:spring-retry:2.0.9' + } tasks.named('test') { diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/ParsingServiceApplication.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/ParsingServiceApplication.java index 2b92de2..8c4db46 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/ParsingServiceApplication.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/ParsingServiceApplication.java @@ -2,8 +2,10 @@ package ru.pricepulse.parsingservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.retry.annotation.EnableRetry; @SpringBootApplication +@EnableRetry public class ParsingServiceApplication { public static void main(String[] args) { diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/config/MarketplacesConfig.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/config/MarketplacesConfig.java index 53c4a88..fd19adb 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/config/MarketplacesConfig.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/config/MarketplacesConfig.java @@ -1,13 +1,20 @@ package ru.pricepulse.parsingservice.config; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import ru.pricepulse.parsingservice.config.properties.OzonConfigProperties; import ru.pricepulse.parsingservice.config.properties.WildberriesConfigProperties; +@Getter @Configuration @EnableConfigurationProperties({ OzonConfigProperties.class, WildberriesConfigProperties.class }) -public class MarketplacesConfig {} +@AllArgsConstructor +public class MarketplacesConfig { + private final WildberriesConfigProperties wildberriesConfigProperties; + private final OzonConfigProperties ozonConfigProperties; +} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/entity/ProductEntity.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/entity/ProductEntity.java index 5c4d968..91d6333 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/entity/ProductEntity.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/entity/ProductEntity.java @@ -39,12 +39,15 @@ public class ProductEntity { @Column(name = "created_at", nullable = false) private LocalDateTime createdAt; - @Column(name = "url", nullable = false) + @Column(name = "url", nullable = false, unique = true) private String url; @Column(name = "image-url", nullable = false) private String imageUrl; + @Column(name = "article", nullable = false) + private String article; + @Override public final boolean equals(Object o) { if (this == o) return true; diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/repository/ProductRepository.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/repository/ProductRepository.java index 3532dea..f76335b 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/repository/ProductRepository.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/persistence/repository/ProductRepository.java @@ -3,8 +3,13 @@ package ru.pricepulse.parsingservice.persistence.repository; import org.springframework.data.jpa.repository.JpaRepository; import ru.pricepulse.parsingservice.persistence.entity.ProductEntity; +import java.util.List; + public interface ProductRepository extends JpaRepository { boolean existsByUrl(String url); + ProductEntity findByUrl(String url); + List findAllByUrlIn(List urls); + } diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/DebugRunner.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/DebugRunner.java deleted file mode 100644 index 50e7fcc..0000000 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/DebugRunner.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.pricepulse.parsingservice.wildberries_parser; - -import lombok.AllArgsConstructor; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Component; -import ru.pricepulse.parsingservice.wildberries_parser.service.WildberriesParsingService; - -@Component -@AllArgsConstructor -public class DebugRunner implements CommandLineRunner { - private final WildberriesParsingService parsingService; - - @Override - public void run(String... args){ - /*System.out.println("Начинаем отладку..."); - parsingService.parse(); - System.out.println("Заканчиваем отладку...");*/ - } -} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/DynamicProxyInterceptor.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/DynamicProxyInterceptor.java new file mode 100644 index 0000000..028c2b0 --- /dev/null +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/DynamicProxyInterceptor.java @@ -0,0 +1,41 @@ +package ru.pricepulse.parsingservice.wildberries_parser.configuration; + +import lombok.extern.slf4j.Slf4j; +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.io.IOException; +import java.net.InetSocketAddress; + +@Slf4j +public class DynamicProxyInterceptor implements ClientHttpRequestInterceptor { + + private final UserAgentProvider userAgentProvider; + private final ProxyProvider proxyProvider; + + public DynamicProxyInterceptor(UserAgentProvider userAgentProvider, ProxyProvider proxyProvider) { + this.userAgentProvider = userAgentProvider; + this.proxyProvider = proxyProvider; + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + // Получаем случайный прокси + InetSocketAddress proxyAddress = proxyProvider.getRandomProxy(); + log.info("Используемый прокси: {}:{}", proxyAddress.getHostName(), proxyAddress.getPort()); + + // Устанавливаем прокси + System.setProperty("http.proxyHost", proxyAddress.getHostName()); + System.setProperty("http.proxyPort", String.valueOf(proxyAddress.getPort())); + + // Устанавливаем динамический user-agent + String randomUserAgent = userAgentProvider.getRandomUserAgent(); + log.info("Используемый User-Agent: {}", randomUserAgent); + request.getHeaders().set("User-Agent", randomUserAgent); + + // Выполняем запрос + return execution.execute(request, body); + } +} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/ProxyProvider.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/ProxyProvider.java new file mode 100644 index 0000000..baf802b --- /dev/null +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/ProxyProvider.java @@ -0,0 +1,21 @@ +package ru.pricepulse.parsingservice.wildberries_parser.configuration; + +import org.springframework.stereotype.Component; + +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Random; + +@Component +public class ProxyProvider { + private static final List proxies = List.of( + "85.215.64.49:80", + "82.115.19.142:80", + "148.113.172.51:8080" + ); + + public InetSocketAddress getRandomProxy() { + String[] proxy = proxies.get(new Random().nextInt(proxies.size())).split(":"); + return new InetSocketAddress(proxy[0], Integer.parseInt(proxy[1])); + } +} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/RestTemplateConfig.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/RestTemplateConfig.java new file mode 100644 index 0000000..cb373ba --- /dev/null +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/RestTemplateConfig.java @@ -0,0 +1,29 @@ +package ru.pricepulse.parsingservice.wildberries_parser.configuration; + +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; + +@Configuration +@AllArgsConstructor +public class RestTemplateConfig { + + private final UserAgentProvider userAgentProvider; + private final ProxyProvider proxyProvider; + + @Bean + public RestTemplate restTemplate() { + RestTemplate restTemplate = new RestTemplate(); + ClientHttpRequestInterceptor dynamicProxyInterceptor = new DynamicProxyInterceptor(userAgentProvider, proxyProvider); + + // Добавляем интерсептор в RestTemplate + restTemplate.setInterceptors(Collections.singletonList(dynamicProxyInterceptor)); + + return restTemplate; + } + +} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/UserAgentProvider.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/UserAgentProvider.java new file mode 100644 index 0000000..cb6cea8 --- /dev/null +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/UserAgentProvider.java @@ -0,0 +1,19 @@ +package ru.pricepulse.parsingservice.wildberries_parser.configuration; + +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Random; + +@Component +public class UserAgentProvider { + private static final List userAgents = List.of( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36", + "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15A372 Safari/604.1" + ); + + public String getRandomUserAgent() { + return userAgents.get(new Random().nextInt(userAgents.size())); + } +} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WbProperties.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WbProperties.java deleted file mode 100644 index 5983506..0000000 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WbProperties.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.pricepulse.parsingservice.wildberries_parser.configuration; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConfigurationProperties(prefix = "marketplace.wildberries") -@Getter -@Setter -public class WbProperties { - private String baseUrl; - private String catalogUrl; - private String userAgent; - private String catalogWbUrl; - private int retryAttempts; - private long retryDelay; - private String laptopUrl; - private String shard; -} diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WebClientConfig.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WebClientConfig.java index 944f9e1..802d9e5 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WebClientConfig.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/configuration/WebClientConfig.java @@ -1,18 +1,58 @@ package ru.pricepulse.parsingservice.wildberries_parser.configuration; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.ProxyProvider; +import java.net.InetSocketAddress; + +@Slf4j @Configuration +@AllArgsConstructor public class WebClientConfig { + private final UserAgentProvider userAgentProvider; + private final ru.pricepulse.parsingservice.wildberries_parser.configuration.ProxyProvider proxyProvider; + + @Bean public WebClient webClient() { return WebClient.builder() - .defaultHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)") + .filter((request, next) -> { + // Получаем случайный прокси для каждого запроса + InetSocketAddress proxyAddress = proxyProvider.getRandomProxy(); + log.info("Используемый прокси: {}:{}", proxyAddress.getHostName(), proxyAddress.getPort()); + + HttpClient httpClient = HttpClient.create() + .proxy(proxy -> proxy + .type(ProxyProvider.Proxy.HTTP) + .address(proxyAddress)); + + String randomUserAgent = userAgentProvider.getRandomUserAgent(); + log.info("Используемый User-Agent: {}", randomUserAgent); + + // Создаем новый WebClient с прокси + WebClient webClientWithProxy = WebClient.builder() + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build(); + + // Выполняем запрос с обновленным User-Agent через WebClient с прокси + return webClientWithProxy + .method(request.method()) + .uri(request.url()) + .headers(headers -> headers.putAll(request.headers())) + .header(HttpHeaders.USER_AGENT, randomUserAgent) + .body(request.body()).exchange(); + }) .codecs(configurer -> configurer .defaultCodecs() .maxInMemorySize(10 * 1024 * 1024)) .build(); } } + diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/converter/ProductInfoDto2ProductEntity.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/converter/ProductInfoDto2ProductEntity.java index 980a44e..2d2abe1 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/converter/ProductInfoDto2ProductEntity.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/converter/ProductInfoDto2ProductEntity.java @@ -20,6 +20,8 @@ public class ProductInfoDto2ProductEntity implements Converter productEntities, List priceHistoryEntities) { + // Получаем URL продуктов + List urls = productEntities.stream() + .map(ProductEntity::getUrl) + .collect(Collectors.toList()); + + // Находим уже существующие URL в базе данных + List existingUrls = productRepository.findAllByUrlIn(urls).stream() + .map(ProductEntity::getUrl) + .toList(); + + // Фильтруем уникальные продукты, которых еще нет в базе + List uniqueProducts = productEntities.stream() + .filter(product -> !existingUrls.contains(product.getUrl())) + .collect(Collectors.toList()); + + // Сохраняем только новые продукты + productRepository.saveAll(uniqueProducts); + + // Создаем мапу для быстрого доступа к продуктам по URL + Map productMap = productRepository.findAllByUrlIn(urls).stream() + .collect(Collectors.toMap(ProductEntity::getUrl, product -> product)); + + // Фильтруем и обновляем идентификаторы для истории цен + List updatedPriceHistories = priceHistoryEntities.stream() + .peek(priceHistory -> { + ProductEntity product = productMap.get(priceHistory.getId().getProduct().getUrl()); + priceHistory.getId().setProduct(product); + }) + .collect(Collectors.toList()); + + // Сохраняем историю цен + productPriceRepository.saveAll(updatedPriceHistories); + } +} + diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/WildberriesParsingService.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/WildberriesParsingService.java index 1e17eac..2ccbc32 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/WildberriesParsingService.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/WildberriesParsingService.java @@ -2,16 +2,13 @@ package ru.pricepulse.parsingservice.wildberries_parser.service; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Service; +import ru.pricepulse.parsingservice.config.MarketplacesConfig; import ru.pricepulse.parsingservice.persistence.entity.PriceHistoryEntity; import ru.pricepulse.parsingservice.persistence.entity.PriceHistoryId; import ru.pricepulse.parsingservice.persistence.entity.ProductEntity; -import ru.pricepulse.parsingservice.persistence.repository.ProductPriceRepository; -import ru.pricepulse.parsingservice.persistence.repository.ProductRepository; -import ru.pricepulse.parsingservice.wildberries_parser.configuration.WbProperties; import ru.pricepulse.parsingservice.wildberries_parser.service.client.Client; import ru.pricepulse.parsingservice.wildberries_parser.service.dto.ProductInfoDto; @@ -21,17 +18,15 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -@Service +@Service("wildberriesParsingService") @AllArgsConstructor public class WildberriesParsingService { private final Client client; private final ObjectMapper objectMapper; private final ConversionService conversionService; - private final ProductRepository productRepository; - private final WbProperties wbProperties; - private final ProductPriceRepository productPriceRepository; + private final MarketplacesConfig marketplacesConfig; + private final ProductService productService; - @Transactional public void parse() { List productEntities = new ArrayList<>(); List priceHistories = new ArrayList<>(); @@ -41,8 +36,8 @@ public class WildberriesParsingService { Integer totalPages = null; do { - var pageData = client.scrapPage(page, wbProperties.getShard(), wbProperties.getLaptopUrl()); - + var pageData = client.scrapPage(page, marketplacesConfig.getWildberriesConfigProperties().getShard(), marketplacesConfig.getWildberriesConfigProperties().getLaptopUrl()); + System.out.println("Получена страница: " + page); if (totalPages == null) { Map dataMap = (Map) pageData.get("data"); int totalElements = (int) dataMap.get("total"); @@ -54,6 +49,7 @@ public class WildberriesParsingService { productInfoDtoList.forEach(dto -> { ProductEntity productEntity = conversionService.convert(dto, ProductEntity.class); + productEntity.setUrl("https://www.wildberries.ru/catalog/" + dto.getId() + "/detail.aspx?targetUrl=BP"); PriceHistoryEntity priceHistory = PriceHistoryEntity.builder() .id(new PriceHistoryId(productEntity.getUrl(), LocalDateTime.now())) @@ -66,9 +62,9 @@ public class WildberriesParsingService { page++; } while (page <= totalPages); +// } while (page <= 5); - productRepository.saveAll(productEntities); - productPriceRepository.saveAll(priceHistories); + productService.saveData(productEntities, priceHistories); } private List convertMapObjectToListProductInfoDto(Map map) { @@ -79,7 +75,8 @@ public class WildberriesParsingService { private List getProductInfoDtos(Map> dataMap) { return objectMapper.convertValue( dataMap.get("products"), - new TypeReference<>() {} + new TypeReference<>() { + } ); } } diff --git a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/client/ClientImpl.java b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/client/ClientImpl.java index d76fccf..45137a4 100644 --- a/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/client/ClientImpl.java +++ b/parsing-service/src/main/java/ru/pricepulse/parsingservice/wildberries_parser/service/client/ClientImpl.java @@ -1,33 +1,72 @@ package ru.pricepulse.parsingservice.wildberries_parser.service.client; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.retry.annotation.Recover; +import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; -import org.springframework.web.reactive.function.client.WebClient; -import ru.pricepulse.parsingservice.wildberries_parser.configuration.WbProperties; +import org.springframework.web.client.RestTemplate; +import ru.pricepulse.parsingservice.config.MarketplacesConfig; +import java.util.Collections; import java.util.Map; @AllArgsConstructor @Service +@Slf4j public class ClientImpl implements Client { - private final WebClient webClient; - private final WbProperties wbProperties; + private final RestTemplate restTemplate; + private final MarketplacesConfig marketplacesConfig; + @Override + @Retryable(maxAttempts = 50, value = RuntimeException.class) public Map scrapPage(int page, String shard, String query) { - String url = wbProperties.getCatalogWbUrl() + + String url = marketplacesConfig.getWildberriesConfigProperties().getCatalogWbUrl() + shard + query + "?dest=-1257786&page=" + page + "&subject=2290"; - return webClient.get() - .uri(url) - .retrieve() - .bodyToMono(new ParameterizedTypeReference>() { - }) - .retry(50) - .block(); + return restTemplate.exchange( + url, + HttpMethod.GET, + HttpEntity.EMPTY, + new ParameterizedTypeReference>() {} + ).getBody(); } + + @Recover + public Map recover(RuntimeException e, int page, String shard, String query) { + // Логика обработки неудачи после всех попыток + log.error("Все попытки завершились неудачей: {}", e.getMessage()); + // Можно вернуть пустую карту или другое значение по умолчанию + return Collections.emptyMap(); + } + + +// @Override +// public Map scrapPage(int page, String shard, String query) { +// String url = marketplacesConfig.getWildberriesConfigProperties().getCatalogWbUrl() + +// shard + +// query + +// "?dest=-1257786&page=" + page + "&subject=2290"; +// +// try { +// TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000) + 500); +// } catch (InterruptedException e) { +// Thread.currentThread().interrupt(); +// } +// +// return webClient.get() +// .uri(url) +// .retrieve() +// .bodyToMono(new ParameterizedTypeReference>() { +// }) +// .retry(50) +// .block(); +// } } diff --git a/parsing-service/src/main/resources/application.yml b/parsing-service/src/main/resources/application.yml index 276294e..fc888c0 100644 --- a/parsing-service/src/main/resources/application.yml +++ b/parsing-service/src/main/resources/application.yml @@ -22,9 +22,11 @@ spring: marketplace: ozon: + status: false categories-urls: - https://www.ozon.ru/category/noutbuki-15692/?brandcertified=t wildberries: + status: true base-url: "https://static-basket-01.wbbasket.ru" catalog-url: "/vol0/data/main-menu-ru-ru-v3.json" user-agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)" @@ -34,8 +36,12 @@ marketplace: shard: "electronic15" laptop-url: "/catalog" + logging: pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %X%n" - - +# level: +# org: +# springframework: +# boot: +# autoconfigure: DEBUG \ No newline at end of file diff --git a/parsing-service/src/main/resources/db/changelog/20240926/20240926_001_create_product_table.xml b/parsing-service/src/main/resources/db/changelog/20240926/20240926_001_create_product_table.xml index cc26229..38a9de0 100644 --- a/parsing-service/src/main/resources/db/changelog/20240926/20240926_001_create_product_table.xml +++ b/parsing-service/src/main/resources/db/changelog/20240926/20240926_001_create_product_table.xml @@ -5,11 +5,6 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd"> - - - - - diff --git a/parsing-service/src/main/resources/db/changelog/20240926/20240926_002_create_price_history_table.xml b/parsing-service/src/main/resources/db/changelog/20240926/20240926_002_create_price_history_table.xml index b193183..666f65c 100644 --- a/parsing-service/src/main/resources/db/changelog/20240926/20240926_002_create_price_history_table.xml +++ b/parsing-service/src/main/resources/db/changelog/20240926/20240926_002_create_price_history_table.xml @@ -5,11 +5,6 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd"> - - - - - diff --git a/parsing-service/src/main/resources/db/changelog/20241014/20241014_add_constraint_on_product_url.xml b/parsing-service/src/main/resources/db/changelog/20241014/20241014_add_constraint_on_product_url.xml new file mode 100644 index 0000000..e3bdf98 --- /dev/null +++ b/parsing-service/src/main/resources/db/changelog/20241014/20241014_add_constraint_on_product_url.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/parsing-service/src/main/resources/db/changelog/20241014/master.yml b/parsing-service/src/main/resources/db/changelog/20241014/master.yml new file mode 100644 index 0000000..93f0849 --- /dev/null +++ b/parsing-service/src/main/resources/db/changelog/20241014/master.yml @@ -0,0 +1,4 @@ +databaseChangeLog: + - include: + file: 20241014_add_constraint_on_product_url.xml + relativeToChangelogFile: true \ No newline at end of file diff --git a/parsing-service/src/main/resources/db/changelog/master.yml b/parsing-service/src/main/resources/db/changelog/master.yml index 845e042..a561947 100644 --- a/parsing-service/src/main/resources/db/changelog/master.yml +++ b/parsing-service/src/main/resources/db/changelog/master.yml @@ -5,3 +5,6 @@ databaseChangeLog: - include: file: 20241006/master.yml relativeToChangelogFile: true + - include: + file: 20241014/master.yml + relativeToChangelogFile: true