Skip to content

Commit 4b82c5c

Browse files
authored
Merge pull request #20 from makeOurCity/feature/update-ping-logic
updated updateEntity on Feature/update ping logic branch
2 parents d726ac9 + 5c9dd45 commit 4b82c5c

3 files changed

Lines changed: 81 additions & 82 deletions

File tree

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@
7272
<artifactId>spring-webmvc</artifactId>
7373
<version>5.3.23</version>
7474
</dependency>
75+
<dependency>
76+
<groupId>com.fasterxml.jackson.core</groupId>
77+
<artifactId>jackson-databind</artifactId>
78+
<version>2.15.2</version>
79+
</dependency>
80+
<dependency>
81+
<groupId>com.fasterxml.jackson.datatype</groupId>
82+
<artifactId>jackson-datatype-jsr310</artifactId>
83+
<version>2.15.2</version>
84+
</dependency>
7585
</dependencies>
7686

7787
<build>

src/main/java/city/makeour/moc/MocClient.java

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
import org.springframework.web.client.RestClient;
88
import org.springframework.web.client.RestClient.ResponseSpec;
99

10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import com.fasterxml.jackson.databind.SerializationFeature;
12+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
13+
import com.fasterxml.jackson.core.type.TypeReference;
14+
1015
import city.makeour.moc.ngsiv2.Ngsiv2Client;
1116
import city.makeour.ngsi.v2.api.EntitiesApi;
1217
import city.makeour.ngsi.v2.invoker.ApiClient;
@@ -149,30 +154,42 @@ public ResponseSpec getEntity(String entityId, String type) {
149154
return this.entities().retrieveEntityWithResponseSpec(entityId, type, null, null, "keyValues");
150155
}
151156

157+
// 指定された ID と Type を持つEntityを削除
158+
public ResponseSpec deleteEntity(String entityId, String type) {
159+
if (entityId == null || entityId.isBlank()) {
160+
throw new IllegalArgumentException("id is required");
161+
}
162+
// EntitiesApi に定義されている removeEntityWithResponseSpec を呼び出す
163+
return this.entities().removeEntityWithResponseSpec(entityId, type);
164+
}
165+
166+
// 指定された ID を持つEntityを削除
167+
public ResponseSpec deleteEntity(String entityId) {
168+
return this.deleteEntity(entityId, null);
169+
}
170+
171+
// Map版(メインロジック)
152172
public ResponseSpec updateEntity(String id, String type, Map<String, Object> attributesToUpdate) {
153173
if (id == null || id.isBlank()) throw new IllegalArgumentException("id is required");
154174
if (type == null || type.isBlank()) throw new IllegalArgumentException("type is required");
155175
if (attributesToUpdate == null) attributesToUpdate = java.util.Collections.emptyMap();
156-
176+
157177
try {
158-
// Existence check
159178
this.entities()
160179
.retrieveEntityWithResponseSpec(id, type, null, null, "keyValues")
161180
.toEntity(Object.class);
162181

163-
// Exists -> POST (keyValues 形式でそのまま送る)
164182
return this.client.updateEntityAttributes(
165183
id,
166184
"application/json",
167-
attributesToUpdate, // Object(Map) をそのまま PATCH
185+
attributesToUpdate,
168186
type,
169187
"keyValues"
170188
);
171189

172190
} catch (org.springframework.web.client.RestClientResponseException e) {
173191
if (e.getStatusCode().value() != 404) throw e;
174192

175-
// Not found -> create (従来通り)
176193
java.util.Map<String, Object> body = new java.util.HashMap<>();
177194
body.put("id", id);
178195
body.put("type", type);
@@ -181,22 +198,13 @@ public ResponseSpec updateEntity(String id, String type, Map<String, Object> att
181198
}
182199
}
183200

184-
// 指定された ID と Type を持つEntityを削除
185-
public ResponseSpec deleteEntity(String entityId, String type) {
186-
if (entityId == null || entityId.isBlank()) {
187-
throw new IllegalArgumentException("id is required");
188-
}
189-
// EntitiesApi に定義されている removeEntityWithResponseSpec を呼び出す
190-
return this.entities().removeEntityWithResponseSpec(entityId, type);
191-
}
192-
193-
// 指定された ID を持つEntityを削除
194-
public ResponseSpec deleteEntity(String entityId) {
195-
return this.deleteEntity(entityId, null);
201+
// Object版(Mapに変換してMap版に委譲)
202+
public ResponseSpec updateEntity(String id, String type, Object o) {
203+
ObjectMapper mapper = new ObjectMapper();
204+
mapper.registerModule(new JavaTimeModule());
205+
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
206+
207+
Map<String, Object> m = mapper.convertValue(o, new TypeReference<Map<String, Object>>() {});
208+
return updateEntity(id, type, m);
196209
}
197-
198-
199-
200-
201-
202210
}

src/test/java/city/makeour/moc/MocClientTest.java

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package city.makeour.moc;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertFalse;
54
import static org.junit.jupiter.api.Assertions.assertNotNull;
65
import static org.junit.jupiter.api.Assertions.assertThrows;
76

@@ -126,10 +125,10 @@ void testAuth() throws GeneralSecurityException, NoSuchAlgorithmException {
126125
@Test
127126
@DisplayName("エンティティを作成・取得できるかのテスト(最小版)")
128127
@EnabledIfEnvironmentVariables({
129-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USER_POOL_ID", matches = ".*"),
130-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_CLIENT_ID", matches = ".*"),
131-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USERNAME", matches = ".*"),
132-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_PASSWORD", matches = ".*")
128+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USER_POOL_ID", matches = ".*"),
129+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_CLIENT_ID", matches = ".*"),
130+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USERNAME", matches = ".*"),
131+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_PASSWORD", matches = ".*")
133132
})
134133
void testCreateAndGetEntity_Minimal() throws GeneralSecurityException, NoSuchAlgorithmException {
135134
MocClient client = new MocClient();
@@ -152,108 +151,90 @@ void testCreateAndGetEntity_Minimal() throws GeneralSecurityException, NoSuchAlg
152151

153152
assertNotNull(retrievedEntity);
154153
assertEquals(entityId, retrievedEntity.getId());
155-
}
154+
}
156155

157156
@Test
158-
@DisplayName("updateEntityのUpsert(作成・更新)ロジックをテストする")
159-
@EnabledIfEnvironmentVariables({
157+
@DisplayName("updateEntityのUpsert(作成・更新)ロジックをテストする")
158+
@EnabledIfEnvironmentVariables({
160159
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USER_POOL_ID", matches = ".*"),
161160
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_CLIENT_ID", matches = ".*"),
162161
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USERNAME", matches = ".*"),
163162
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_PASSWORD", matches = ".*")
164-
})
163+
})
165164
void testUpdateEntity_UpsertLogic() throws GeneralSecurityException, NoSuchAlgorithmException {
166165
MocClient client = new MocClient();
167166
client.setMocAuthInfo(System.getenv("TEST_COGNITO_USER_POOL_ID"), System.getenv("TEST_COGNITO_CLIENT_ID"));
168167
client.login(System.getenv("TEST_COGNITO_USERNAME"), System.getenv("TEST_COGNITO_PASSWORD"));
169-
168+
170169
String entityId = "urn:ngsi-ld:TestUpsert:" + UUID.randomUUID().toString();
171170
String entityType = "TestUpsertType";
172-
171+
173172
// 1. "作成" (Insert) pathのテスト
174173
// エンティティが存在しない --> catchブロックの this.createEntity
175174
Map<String, Object> initialAttrs = new HashMap<>();
176175
initialAttrs.put("temperature", 25);
177176
initialAttrs.put("humidity", 50); // "temperature" 以外の属性も指定
178-
177+
179178
client.updateEntity(entityId, entityType, initialAttrs);
180-
179+
181180
// 検証 (作成)
182-
ParameterizedTypeReference<Map<String, Object>> mapType = new ParameterizedTypeReference<>() {};
181+
ParameterizedTypeReference<Map<String, Object>> mapType = new ParameterizedTypeReference<>() {
182+
};
183183
Map<String, Object> createdEntity = client.getEntity(entityId, entityType).body(mapType);
184-
184+
185185
assertNotNull(createdEntity);
186186
assertEquals(entityId, createdEntity.get("id"));
187187
assertEquals(25, createdEntity.get("temperature"));
188188
assertEquals(50, createdEntity.get("humidity"));
189-
189+
190190
// 2. "更新" (Update/PATCH) pathのテスト
191191
// エンティティが既に存在する --> tryブロックの updateExistingEntityAttributesWithResponseSpec
192192
Map<String, Object> updateAttrs = new HashMap<>();
193-
updateAttrs.put("temperature", 30); // 更新
194-
updateAttrs.put("seatNumber", 10); // 追加
193+
updateAttrs.put("temperature", 30); // 更新
194+
updateAttrs.put("seatNumber", 10); // 追加
195195
updateAttrs.put("status", "active");
196-
196+
197197
client.updateEntity(entityId, entityType, updateAttrs);
198-
198+
199199
// 検証 (更新)
200200
Map<String, Object> updatedEntity = client.getEntity(entityId, entityType).body(mapType);
201-
201+
202202
assertNotNull(updatedEntity);
203203
// 更新・追加されている
204204
assertEquals(30, updatedEntity.get("temperature"));
205205
assertEquals(10, updatedEntity.get("seatNumber"));
206206
// 最初の作成時から変更されず残っている
207207
assertEquals(50, updatedEntity.get("humidity"));
208-
208+
209209
assertEquals("active", updatedEntity.get("status"));
210210
}
211211

212212
@Test
213-
@DisplayName("deleteEntityのテスト(ID+Type指定、IDのみ指定の2パターン)")
213+
@DisplayName("エンティティを作成・削除できるかのテスト")
214214
@EnabledIfEnvironmentVariables({
215-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USER_POOL_ID", matches = ".*"),
216-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_CLIENT_ID", matches = ".*"),
217-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USERNAME", matches = ".*"),
218-
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_PASSWORD", matches = ".*")
215+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USER_POOL_ID", matches = ".*"),
216+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_CLIENT_ID", matches = ".*"),
217+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_USERNAME", matches = ".*"),
218+
@EnabledIfEnvironmentVariable(named = "TEST_COGNITO_PASSWORD", matches = ".*")
219219
})
220220
void testDeleteEntity() throws GeneralSecurityException, NoSuchAlgorithmException {
221-
// 1. セットアップ
222221
MocClient client = new MocClient();
223222
client.setMocAuthInfo(System.getenv("TEST_COGNITO_USER_POOL_ID"), System.getenv("TEST_COGNITO_CLIENT_ID"));
224223
client.login(System.getenv("TEST_COGNITO_USERNAME"), System.getenv("TEST_COGNITO_PASSWORD"));
225-
226-
String type = "TestDeleteType";
227-
228-
// ケース 1: deleteEntity(id, type)
229-
String id1 = "urn:ngsi-ld:TestDelete:1:" + UUID.randomUUID().toString();
230-
231-
// データ作成(既存のupdateEntityを利用して作成)
232-
client.updateEntity(id1, type, Map.of("value", 100));
233-
234-
// 削除実行(テスト対象)
235-
client.deleteEntity(id1, type).toBodilessEntity();
236-
237-
// 検証: 取得しようとして 404 Not Found になることを確認
238-
RestClientResponseException ex1 = assertThrows(RestClientResponseException.class, () -> {
239-
client.getEntity(id1, type).toBodilessEntity();
240-
});
241-
assertEquals(HttpStatus.NOT_FOUND.value(), ex1.getStatusCode().value());
242-
243-
// ケース 2: deleteEntity(id) - IDのみでの削除
244-
String id2 = "urn:ngsi-ld:TestDelete:2:" + UUID.randomUUID().toString();
245-
246-
// データ作成
247-
client.updateEntity(id2, type, Map.of("value", 200));
248-
249-
// 削除実行(テスト対象)
250-
client.deleteEntity(id2).toBodilessEntity();
251-
252-
// 検証: 取得しようとして 404 Not Found になることを確認
253-
RestClientResponseException ex2 = assertThrows(RestClientResponseException.class, () -> {
254-
client.getEntity(id2, type).toBodilessEntity();
224+
225+
// エンティティを作成
226+
String entityId = "urn:ngsi-ld:TestEntity:" + UUID.randomUUID().toString();
227+
CreateEntityRequest entity = new CreateEntityRequest();
228+
entity.setType("TestEntity");
229+
entity.setId(entityId);
230+
client.entities().createEntity("application/json", entity, "keyValues");
231+
232+
// 削除を実行
233+
client.deleteEntity(entityId, "TestEntity");
234+
235+
// 削除後に取得しようとすると404が返ることを確認
236+
assertThrows(RestClientResponseException.class, () -> {
237+
client.getEntity(entityId, "TestEntity").body(RetrieveEntityResponse.class);
255238
});
256-
assertEquals(HttpStatus.NOT_FOUND.value(), ex2.getStatusCode().value());
257239
}
258-
259240
}

0 commit comments

Comments
 (0)