From fd5414e2a111997ec3c80084536ee5b59dedb249 Mon Sep 17 00:00:00 2001 From: min-96 Date: Thu, 10 Oct 2024 09:08:56 +0900 Subject: [PATCH 1/3] refactor NftResponse --- src/main/kotlin/com/api/nft/event/dto/NftResponse.kt | 1 + src/main/kotlin/com/api/nft/service/api/NftService.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/kotlin/com/api/nft/event/dto/NftResponse.kt b/src/main/kotlin/com/api/nft/event/dto/NftResponse.kt index e4df42a..5d5c4b4 100644 --- a/src/main/kotlin/com/api/nft/event/dto/NftResponse.kt +++ b/src/main/kotlin/com/api/nft/event/dto/NftResponse.kt @@ -7,4 +7,5 @@ data class NftResponse( val tokenId: String, val tokenAddress: String, val chainType: ChainType, + val collectionName: String, ) diff --git a/src/main/kotlin/com/api/nft/service/api/NftService.kt b/src/main/kotlin/com/api/nft/service/api/NftService.kt index 4f21745..aaa2109 100644 --- a/src/main/kotlin/com/api/nft/service/api/NftService.kt +++ b/src/main/kotlin/com/api/nft/service/api/NftService.kt @@ -96,6 +96,7 @@ class NftService( tokenId = this.tokenId, tokenAddress = this.tokenAddress, chainType = this.chainType, + collectionName = this.collectionName ) fun getNftData(request: NftData, chainType: ChainType): Mono?>> { From 68519fda370488732f1956f3900c834ff44971b0 Mon Sep 17 00:00:00 2001 From: min-96 Date: Mon, 14 Oct 2024 00:53:58 +0900 Subject: [PATCH 2/3] feat: api of nftDetail --- .../com/api/nft/controller/NftController.kt | 8 ---- .../domain/attribute/AttributeRepository.kt | 3 ++ .../metadata/repository/MetadataRepository.kt | 3 ++ .../api/nft/properties/MarketApiProperties.kt | 8 ++++ .../api/nft/service/api/AttributeService.kt | 5 +++ .../api/nft/service/api/MetadataService.kt | 3 ++ .../api/nft/service/api/NftAuctionService.kt | 4 ++ .../api/nft/service/api/NftListingService.kt | 4 ++ .../com/api/nft/service/api/NftService.kt | 44 +++++++++++++++++++ .../api/nft/service/dto/NftClientResponse.kt | 14 ++++++ .../api/nft/service/dto/NftDetailResponse.kt | 20 +++++++++ .../nft/service/{ => dto}/TransferResponse.kt | 2 +- .../nft/service/external/MarketApiService.kt | 39 ++++++++++++++++ 13 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/com/api/nft/properties/MarketApiProperties.kt create mode 100644 src/main/kotlin/com/api/nft/service/dto/NftClientResponse.kt create mode 100644 src/main/kotlin/com/api/nft/service/dto/NftDetailResponse.kt rename src/main/kotlin/com/api/nft/service/{ => dto}/TransferResponse.kt (80%) create mode 100644 src/main/kotlin/com/api/nft/service/external/MarketApiService.kt diff --git a/src/main/kotlin/com/api/nft/controller/NftController.kt b/src/main/kotlin/com/api/nft/controller/NftController.kt index 1e682a8..3d10f00 100644 --- a/src/main/kotlin/com/api/nft/controller/NftController.kt +++ b/src/main/kotlin/com/api/nft/controller/NftController.kt @@ -56,12 +56,4 @@ class NftController( return nftService.getByWalletNft(wallet,chainType) } - // collection을 구현할건데 1h / 7h /12h / 24h / 7d/ 30d - // Listing은 matched volume 이 높은순이여야돼 - - - - // aution은 현재 acution중인것 - - } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/domain/attribute/AttributeRepository.kt b/src/main/kotlin/com/api/nft/domain/attribute/AttributeRepository.kt index 8542b5a..2d25076 100644 --- a/src/main/kotlin/com/api/nft/domain/attribute/AttributeRepository.kt +++ b/src/main/kotlin/com/api/nft/domain/attribute/AttributeRepository.kt @@ -1,6 +1,9 @@ package com.api.nft.domain.attribute import org.springframework.data.repository.reactive.ReactiveCrudRepository +import reactor.core.publisher.Flux interface AttributeRepository : ReactiveCrudRepository { + + fun findAllByNftId(nftId: Long): Flux } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/domain/metadata/repository/MetadataRepository.kt b/src/main/kotlin/com/api/nft/domain/metadata/repository/MetadataRepository.kt index 096ddad..7b64c59 100644 --- a/src/main/kotlin/com/api/nft/domain/metadata/repository/MetadataRepository.kt +++ b/src/main/kotlin/com/api/nft/domain/metadata/repository/MetadataRepository.kt @@ -2,6 +2,9 @@ package com.api.nft.domain.metadata.repository import com.api.nft.domain.metadata.Metadata import org.springframework.data.repository.reactive.ReactiveCrudRepository +import reactor.core.publisher.Mono interface MetadataRepository: ReactiveCrudRepository { + + fun findByNftId(nftId: Long) : Mono } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/properties/MarketApiProperties.kt b/src/main/kotlin/com/api/nft/properties/MarketApiProperties.kt new file mode 100644 index 0000000..473df8d --- /dev/null +++ b/src/main/kotlin/com/api/nft/properties/MarketApiProperties.kt @@ -0,0 +1,8 @@ +package com.api.nft.properties + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties(prefix = "market") +data class MarketApiProperties( + val uri: String +) diff --git a/src/main/kotlin/com/api/nft/service/api/AttributeService.kt b/src/main/kotlin/com/api/nft/service/api/AttributeService.kt index ce2e57f..d515605 100644 --- a/src/main/kotlin/com/api/nft/service/api/AttributeService.kt +++ b/src/main/kotlin/com/api/nft/service/api/AttributeService.kt @@ -5,6 +5,7 @@ import com.api.nft.domain.attribute.AttributeRepository import com.api.nft.service.external.dto.NftAttribute import org.springframework.stereotype.Service import reactor.core.publisher.Flux +import reactor.core.publisher.Mono @Service class AttributeService( @@ -22,4 +23,8 @@ class AttributeService( ) } } + + fun findByAttribute(nftId: Long): Flux { + return attributeRepository.findAllByNftId(nftId) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/service/api/MetadataService.kt b/src/main/kotlin/com/api/nft/service/api/MetadataService.kt index 10da639..8c0e4eb 100644 --- a/src/main/kotlin/com/api/nft/service/api/MetadataService.kt +++ b/src/main/kotlin/com/api/nft/service/api/MetadataService.kt @@ -20,6 +20,9 @@ class MetadataService( animationUrl = metadata.animationUrl, ) ) + } + fun findByMetadata(nftId: Long): Mono { + return metadataRepository.findByNftId(nftId) } } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/service/api/NftAuctionService.kt b/src/main/kotlin/com/api/nft/service/api/NftAuctionService.kt index 8fee8cb..2a4d356 100644 --- a/src/main/kotlin/com/api/nft/service/api/NftAuctionService.kt +++ b/src/main/kotlin/com/api/nft/service/api/NftAuctionService.kt @@ -47,4 +47,8 @@ class NftAuctionService( ) ).then() } + + fun findByNftId(nftId: Long): Mono { + return nftAuctionRepository.findByNftId(nftId) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/service/api/NftListingService.kt b/src/main/kotlin/com/api/nft/service/api/NftListingService.kt index 0850702..bfb17d8 100644 --- a/src/main/kotlin/com/api/nft/service/api/NftListingService.kt +++ b/src/main/kotlin/com/api/nft/service/api/NftListingService.kt @@ -52,4 +52,8 @@ class NftListingService( ) } + fun findByNftId(nftId: Long): Mono { + return nftListingRepository.findByNftId(nftId) + } + } \ No newline at end of file diff --git a/src/main/kotlin/com/api/nft/service/api/NftService.kt b/src/main/kotlin/com/api/nft/service/api/NftService.kt index aaa2109..8d878f5 100644 --- a/src/main/kotlin/com/api/nft/service/api/NftService.kt +++ b/src/main/kotlin/com/api/nft/service/api/NftService.kt @@ -8,6 +8,8 @@ import com.api.nft.enums.ContractType import com.api.nft.event.dto.NftCreatedEvent import com.api.nft.event.dto.NftResponse import com.api.nft.service.RedisService +import com.api.nft.service.dto.NftDetailResponse +import com.api.nft.service.external.MarketApiService import com.api.nft.service.external.dto.NftAttribute import com.api.nft.service.external.dto.NftData import com.api.nft.service.external.dto.NftMetadata @@ -27,8 +29,50 @@ class NftService( private val transferService: TransferService, private val moralisApiService: MoralisApiService, private val redisService: RedisService, + private val marketApiService: MarketApiService, + private val nftListingService: NftListingService, + private val nftAuctionService: NftAuctionService, ) { + fun findByNftDetail1(nftId: Long): Mono { + return nftRepository.findById(nftId) + .flatMap { nft -> + val metadataMono = metadataService.findByMetadata(nftId) + val attributeMono = attributeService.findByAttribute(nftId).collectList() + val transferMono = transferService.findOrUpdateByNftId(nftId).collectList() + val listingMono = nftListingService.findByNftId(nftId) + val auctionMono = nftAuctionService.findByNftId(nftId) + .flatMap { auction -> + marketApiService.getOfferHistory(auction.id).collectList() + .map { offers -> auction to offers } + }.defaultIfEmpty(null to emptyList()) + + val ledgerMono = marketApiService.getLedgerHistory(nftId).collectList() + + Mono.zip(metadataMono, attributeMono, transferMono, listingMono, auctionMono, ledgerMono) + .map { tuple -> + val metadata = tuple.t1 + val attributes = tuple.t2 + val transfers = tuple.t3 + val listing = tuple.t4 + val (auction, offers) = tuple.t5 + val ledgers = tuple.t6 + + NftDetailResponse( + nft = nft, + metadata = metadata, + attributes = attributes, + transfers = transfers, + listing = listing, + auction = auction, + offers = offers, + ledgers = ledgers, + ) + } + } + } + + fun findAllById(ids: List): Flux { return nftRepository.findAllByNftJoinMetadata(ids) .flatMap { nft -> diff --git a/src/main/kotlin/com/api/nft/service/dto/NftClientResponse.kt b/src/main/kotlin/com/api/nft/service/dto/NftClientResponse.kt new file mode 100644 index 0000000..8725bbc --- /dev/null +++ b/src/main/kotlin/com/api/nft/service/dto/NftClientResponse.kt @@ -0,0 +1,14 @@ +package com.api.nft.service.dto + +import com.api.nft.enums.ChainType +import com.api.nft.enums.ContractType + +data class NftClientResponse( + val id: Long, + val tokenId: String, + val tokenAddress: String, + val chainType: ChainType, + val contractType: ContractType, + val nftName: String, + val tokenHash: String, +) diff --git a/src/main/kotlin/com/api/nft/service/dto/NftDetailResponse.kt b/src/main/kotlin/com/api/nft/service/dto/NftDetailResponse.kt new file mode 100644 index 0000000..aa8c065 --- /dev/null +++ b/src/main/kotlin/com/api/nft/service/dto/NftDetailResponse.kt @@ -0,0 +1,20 @@ +package com.api.nft.service.dto + +import com.api.nft.domain.attribute.Attribute +import com.api.nft.domain.metadata.Metadata +import com.api.nft.domain.nft.Nft +import com.api.nft.domain.nft.NftAuction +import com.api.nft.domain.nft.NftListing +import com.api.nft.domain.trasfer.Transfer + + +data class NftDetailResponse( + val nft : Nft, + val metadata : Metadata, + val attributes : List, + val transfers : List, + val listing : NftListing?, + val auction : NftAuction?, + val offers: List?, + val ledgers: List? +) diff --git a/src/main/kotlin/com/api/nft/service/TransferResponse.kt b/src/main/kotlin/com/api/nft/service/dto/TransferResponse.kt similarity index 80% rename from src/main/kotlin/com/api/nft/service/TransferResponse.kt rename to src/main/kotlin/com/api/nft/service/dto/TransferResponse.kt index cb414bc..d55f12b 100644 --- a/src/main/kotlin/com/api/nft/service/TransferResponse.kt +++ b/src/main/kotlin/com/api/nft/service/dto/TransferResponse.kt @@ -1,4 +1,4 @@ -package com.api.nft.service +package com.api.nft.service.dto import java.math.BigInteger diff --git a/src/main/kotlin/com/api/nft/service/external/MarketApiService.kt b/src/main/kotlin/com/api/nft/service/external/MarketApiService.kt new file mode 100644 index 0000000..f13f44f --- /dev/null +++ b/src/main/kotlin/com/api/nft/service/external/MarketApiService.kt @@ -0,0 +1,39 @@ +package com.api.nft.service.external + +import com.api.nft.properties.MarketApiProperties +import org.springframework.stereotype.Service +import org.springframework.web.reactive.function.client.WebClient +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono + +@Service +class MarketApiService( + marketApiProperties: MarketApiProperties +) { + private val webClient = WebClient.builder() + .baseUrl(marketApiProperties.uri ) + .build() + + //TODO("") + fun getOfferHistory(nftId: Long): Flux { + return webClient.get() + .uri{ + it.path("/v1/offer/history") + .queryParam("nftId", nftId) + it.build() + } + .retrieve() + .bodyToFlux(Any::class.java) + } + //TODO("") + fun getLedgerHistory(nftId: Long): Flux { + return webClient.get() + .uri{ + it.path("/v1/orders/history") + .queryParam("nftId", nftId) + it.build() + } + .retrieve() + .bodyToFlux(Any::class.java) + } +} \ No newline at end of file From 2cb88a860c45f85cf7d7c0146c236c9d58e0bc8e Mon Sep 17 00:00:00 2001 From: min-96 Date: Thu, 17 Oct 2024 15:00:16 +0900 Subject: [PATCH 3/3] fix: kafka activate ackMode --- src/main/kotlin/com/api/nft/config/KafkaConfig.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/com/api/nft/config/KafkaConfig.kt b/src/main/kotlin/com/api/nft/config/KafkaConfig.kt index 5eac751..c5acef0 100644 --- a/src/main/kotlin/com/api/nft/config/KafkaConfig.kt +++ b/src/main/kotlin/com/api/nft/config/KafkaConfig.kt @@ -15,6 +15,7 @@ import org.springframework.kafka.core.ConsumerFactory import org.springframework.kafka.core.DefaultKafkaConsumerFactory import org.springframework.kafka.core.KafkaAdmin import org.springframework.kafka.listener.CommonErrorHandler +import org.springframework.kafka.listener.ContainerProperties import org.springframework.kafka.listener.MessageListenerContainer import org.springframework.kafka.support.serializer.JsonDeserializer @@ -48,6 +49,7 @@ class KafkaConfig { val factory = ConcurrentKafkaListenerContainerFactory() factory.consumerFactory = consumerFactory() factory.setConcurrency(4) + factory.containerProperties.ackMode = ContainerProperties.AckMode.RECORD factory.setCommonErrorHandler( object : CommonErrorHandler { override fun handleRemaining(