Skip to content

Commit 5b0bf68

Browse files
authored
Merge pull request #139 from averak/feature/138-friend-send-request-v1
Friend.SendRequestV1を実装
2 parents 7b61b89 + fc2ce22 commit 5b0bf68

File tree

24 files changed

+1551
-176
lines changed

24 files changed

+1551
-176
lines changed

app/adapter/src/main/java/net/averak/gsync/adapter/dao/dto/base/PlayerDto.java

Lines changed: 3 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/adapter/src/main/java/net/averak/gsync/adapter/dao/dto/base/PlayerExample.java

Lines changed: 0 additions & 70 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/adapter/src/main/java/net/averak/gsync/adapter/dao/dto/extend/PlayerILDto.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package net.averak.gsync.adapter.dao.dto.extend;
22

3-
import java.time.LocalDateTime;
4-
5-
import javax.annotation.Nonnull;
6-
import javax.annotation.Nullable;
7-
8-
import org.jetbrains.annotations.NotNull;
9-
103
import net.averak.gsync.adapter.dao.dto.base.PlayerDto;
114
import net.averak.gsync.adapter.dao.dto.base.PlayerLoginDto;
125
import net.averak.gsync.adapter.dao.dto.base.PlayerProfileDto;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
import javax.annotation.Nonnull;
9+
import javax.annotation.Nullable;
10+
import java.time.LocalDateTime;
1311

1412
@SuppressWarnings({"NotNullFieldNotInitialized", "java:S2637"})
1513
public class PlayerILDto extends PlayerDto {
@@ -20,9 +18,9 @@ public class PlayerILDto extends PlayerDto {
2018
@Nullable
2119
PlayerLoginDto playerLogin;
2220

23-
public PlayerILDto(@NotNull String playerId, @NotNull String friendId, @NotNull Boolean isBanned,
24-
@NotNull LocalDateTime createdAt, @NotNull LocalDateTime updatedAt) {
25-
super(playerId, friendId, isBanned, createdAt, updatedAt);
21+
public PlayerILDto(@NotNull String playerId, @NotNull Boolean isBanned, @NotNull LocalDateTime createdAt,
22+
@NotNull LocalDateTime updatedAt) {
23+
super(playerId, isBanned, createdAt, updatedAt);
2624
}
2725

2826
@Nonnull

app/adapter/src/main/kotlin/net/averak/gsync/adapter/handler/player_api/FriendHandler.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package net.averak.gsync.adapter.handler.player_api
33
import net.averak.gsync.adapter.handler.player_api.pbconv.FriendConverter
44
import net.averak.gsync.infrastructure.grpc.player_api.Request
55
import net.averak.gsync.schema.protobuf.player_api.FriendListV1
6+
import net.averak.gsync.schema.protobuf.player_api.FriendSendRequestV1
67
import net.averak.gsync.schema.protobuf.player_api.IFriendHandler
78
import net.averak.gsync.usecase.FriendUsecase
89
import org.springframework.stereotype.Service
10+
import java.util.*
911

1012
@Service
1113
class FriendHandler(
@@ -20,4 +22,9 @@ class FriendHandler(
2022
.addAllReceivedFriendRequests(result.receivedFriendRequests.map { FriendConverter.toPb(it) })
2123
.build()
2224
}
25+
26+
override fun sendRequestV1(request: Request<FriendSendRequestV1.Request>): FriendSendRequestV1.Response {
27+
friendUsecase.sendRequest(request.gctx, request.mustPrincipal().playerID, UUID.fromString(request.message.playerId))
28+
return FriendSendRequestV1.Response.newBuilder().build()
29+
}
2330
}

app/adapter/src/main/kotlin/net/averak/gsync/adapter/handler/player_api/interceptor/AccessLogInterceptor.kt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.google.protobuf.GeneratedMessageV3
44
import com.google.protobuf.util.JsonFormat
55
import io.grpc.*
66
import net.averak.gsync.core.logger.Logger
7-
import net.averak.gsync.infrastructure.grpc.player_api.metadata.OutgoingTrailerKey
87
import net.averak.gsync.infrastructure.grpc.player_api.metadata.RequestScope
98
import net.averak.gsync.infrastructure.json.JsonUtils
109
import org.springframework.core.annotation.Order
@@ -35,7 +34,7 @@ class AccessLogInterceptor(
3534
next.startCall(
3635
object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
3736

38-
lateinit var end: LocalDateTime
37+
var end: LocalDateTime? = null
3938

4039
@Suppress("kotlin:S108")
4140
override fun sendMessage(message: RespT) {
@@ -63,14 +62,6 @@ class AccessLogInterceptor(
6362
logger.info("access log", logMessage)
6463
super.sendMessage(message)
6564
}
66-
67-
override fun close(status: Status, trailers: Metadata) {
68-
trailers.put(
69-
Metadata.Key.of(OutgoingTrailerKey.RESPOND_TIMESTAMP.key, Metadata.ASCII_STRING_MARSHALLER),
70-
end.toString(),
71-
)
72-
super.close(status, trailers)
73-
}
7465
},
7566
headers,
7667
)

app/adapter/src/main/kotlin/net/averak/gsync/adapter/repository/PlayerRepository.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ open class PlayerRepository(
3535
// クエリ数が多いので、プロフィールとログイン履歴は別モデルに切り出した方が良いかもしれない
3636
val dto = PlayerDto(
3737
player.id.toString(),
38-
player.friendID.toString(),
3938
player.isBanned,
4039
)
4140
playerMapper.syncOriginal(dto)
@@ -69,7 +68,6 @@ open class PlayerRepository(
6968
fun convertDtoToModel(dto: PlayerILDto): Player {
7069
return Player(
7170
id = UUID.fromString(dto.playerId),
72-
friendID = UUID.fromString(dto.friendId),
7371
isBanned = dto.isBanned,
7472
profile = convertDtoToModel(dto.playerProfile),
7573
login = dto.playerLogin?.let {

app/adapter/src/test/groovy/net/averak/gsync/adapter/handler/player_api/FriendHandler_ListV1_IT.groovy

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package net.averak.gsync.adapter.handler.player_api
22

3+
import io.grpc.Status
34
import net.averak.gsync.core.game_context.GameContext
45
import net.averak.gsync.domain.model.FriendRequest
56
import net.averak.gsync.domain.model.Friendship
67
import net.averak.gsync.schema.protobuf.player_api.FriendListV1
8+
import net.averak.gsync.schema.protobuf.player_api.FriendSendRequestV1
79
import net.averak.gsync.testkit.AbstractDatabaseSpec
810
import net.averak.gsync.testkit.Faker
11+
import net.averak.gsync.testkit.api.grpc.Response
12+
import net.averak.gsync.testkit.fixture.builder.master.FriendSettingBuilder
13+
import net.averak.gsync.testkit.fixture.builder.master.MasterDataBuilder
914
import net.averak.gsync.testkit.fixture.builder.player.PlayerDataBuilder
1015

1116
import java.time.LocalDateTime
@@ -62,3 +67,91 @@ class FriendHandler_ListV1_IT extends AbstractDatabaseSpec {
6267
}
6368
}
6469
}
70+
71+
class FriendHandler_SendRequestV1_IT extends AbstractDatabaseSpec {
72+
73+
def "フレンドリクエストを送信する"() {
74+
given:
75+
final gctx = Faker.fake(GameContext)
76+
masterUp.setup(
77+
gctx,
78+
new MasterDataBuilder()
79+
.friendSetting(new FriendSettingBuilder().maxFriendRequestCount(2).build())
80+
.build(),
81+
)
82+
playerUp.setup(
83+
gctx,
84+
new PlayerDataBuilder(Faker.uuidv5("p1")).build(),
85+
new PlayerDataBuilder(Faker.uuidv5("p2")).build(),
86+
new PlayerDataBuilder(Faker.uuidv5("p3")).build(),
87+
new PlayerDataBuilder(Faker.uuidv5("p4")).build(),
88+
)
89+
testcase.given()
90+
91+
when:
92+
final response = grpcTester.invoke(
93+
grpcTester.friend.&sendRequestV1,
94+
testcase.when.request,
95+
) {
96+
it.session(Faker.uuidv5("p1"), Faker.uuidv5("g1"))
97+
it.spoofingMasterVersion(gctx.masterVersion)
98+
}
99+
100+
then:
101+
testcase.then(response)
102+
103+
where:
104+
testcase << [
105+
[
106+
name : "フレンドリクエスト送信上限に達していない場合、送信できる",
107+
given: () -> {
108+
playerUp.setup(
109+
new PlayerDataBuilder(Faker.uuidv5("p1"))
110+
.friendRequests(
111+
new FriendRequest(Faker.uuidv5("p1"), Faker.uuidv5("p2"), LocalDateTime.now()),
112+
)
113+
.build(),
114+
)
115+
},
116+
when : [
117+
request: FriendSendRequestV1.Request.newBuilder()
118+
.setPlayerId(Faker.uuidv5("p3").toString())
119+
.build(),
120+
],
121+
then : (Response<FriendSendRequestV1.Response> v) -> {
122+
assert v.status == Status.OK
123+
with(sql.rows("SELECT * FROM gsync_player_friend_request")) {
124+
assert it.size() == 2
125+
assert it*.player_id.sort() == [Faker.uuidv5("p1").toString(), Faker.uuidv5("p1").toString()].sort()
126+
assert it*.receiver_player_id.sort() == [Faker.uuidv5("p2").toString(), Faker.uuidv5("p3").toString()].sort()
127+
}
128+
return true
129+
},
130+
],
131+
[
132+
name : "フレンドリクエスト送信上限に達している場合、送信できない",
133+
given: () -> {
134+
playerUp.setup(
135+
new PlayerDataBuilder(Faker.uuidv5("p1"))
136+
.friendRequests(
137+
new FriendRequest(Faker.uuidv5("p1"), Faker.uuidv5("p2"), LocalDateTime.now()),
138+
new FriendRequest(Faker.uuidv5("p1"), Faker.uuidv5("p3"), LocalDateTime.now()),
139+
)
140+
.build(),
141+
)
142+
},
143+
when : [
144+
request: FriendSendRequestV1.Request.newBuilder()
145+
.setPlayerId(Faker.uuidv5("p4").toString())
146+
.build(),
147+
],
148+
then : (Response<FriendSendRequestV1.Response> v) -> {
149+
assert v.status.code == Status.ABORTED.code
150+
assert v.status.description == "player sent friend requests is over max count."
151+
return true
152+
},
153+
],
154+
]
155+
}
156+
157+
}

app/domain/src/main/kotlin/net/averak/gsync/domain/model/Player.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import java.util.*
55

66
data class Player(
77
val id: UUID,
8-
val friendID: UUID,
98
val isBanned: Boolean,
109
val profile: PlayerProfile,
1110
var login: PlayerLogin?,

app/infrastructure/src/main/kotlin/net/averak/gsync/infrastructure/grpc/player_api/HandlerWrapper.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.averak.gsync.infrastructure.grpc.player_api
22

33
import com.google.protobuf.AbstractMessage
4+
import io.grpc.Status
45
import io.grpc.stub.StreamObserver
56
import net.averak.gsync.infrastructure.grpc.player_api.metadata.RequestScope
67
import org.springframework.stereotype.Component
@@ -32,10 +33,14 @@ class HandlerWrapper(
3233
try {
3334
val response = method(request)
3435
responseObserver.onNext(response)
35-
} catch (ex: Exception) {
36-
responseObserver.onError(ex)
37-
} finally {
3836
responseObserver.onCompleted()
37+
} catch (ex: Exception) {
38+
responseObserver.onError(
39+
Status.ABORTED
40+
.withDescription(ex.message)
41+
.withCause(ex)
42+
.asRuntimeException(),
43+
)
3944
}
4045
}
4146
}

0 commit comments

Comments
 (0)