Skip to content

Commit b937771

Browse files
feat(CRater): Ping endpoint (#304)
Co-authored-by: Hiroki Terashima <honchikun@gmail.com>
1 parent 846266c commit b937771

6 files changed

Lines changed: 184 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.wise.portal.service.ping;
2+
3+
public interface CRaterPingService {
4+
public boolean hasPingedItem(String itemId);
5+
public void cachePingedItem(String itemId, int ttl);
6+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.wise.portal.service.ping.impl;
2+
3+
import java.time.Duration;
4+
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.data.redis.core.StringRedisTemplate;
7+
import org.springframework.stereotype.Service;
8+
import org.wise.portal.service.ping.CRaterPingService;
9+
10+
@Service
11+
public class CRaterPingServiceImpl implements CRaterPingService {
12+
@Autowired
13+
private StringRedisTemplate stringRedisTemplate;
14+
15+
public boolean hasPingedItem(String itemId) {
16+
return stringRedisTemplate.opsForValue().size(itemId) == 1;
17+
}
18+
19+
public void cachePingedItem(String itemId, int ttl) {
20+
this.stringRedisTemplate.opsForValue().setIfAbsent(itemId, "pinged");
21+
this.stringRedisTemplate.expire(itemId, Duration.ofSeconds(ttl));
22+
}
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.wise.vle.domain.webservice.crater;
2+
3+
import org.json.JSONException;
4+
import org.json.JSONObject;
5+
6+
import lombok.Setter;
7+
8+
@Setter
9+
public class CRaterPingRequest extends AbstractCRaterRequest {
10+
public String generateBodyData() throws JSONException {
11+
JSONObject body = new JSONObject(super.generateBodyData());
12+
body.put("service", "LoadService");
13+
return body.toString();
14+
}
15+
16+
@Override
17+
public String getCRaterUrlVariableBase() {
18+
return "cRater_scoring_url";
19+
}
20+
21+
public String getItemId() {
22+
return this.itemId;
23+
}
24+
}

src/main/java/org/wise/vle/web/CRaterController.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.springframework.web.bind.annotation.RequestMapping;
3232
import org.springframework.web.bind.annotation.RestController;
3333
import org.wise.vle.domain.webservice.crater.CRaterVerificationRequest;
34+
import org.wise.portal.service.ping.CRaterPingService;
35+
import org.wise.vle.domain.webservice.crater.CRaterPingRequest;
3436
import org.wise.vle.domain.webservice.crater.CRaterScoringRequest;
3537
import org.wise.vle.domain.webservice.crater.CRaterService;
3638

@@ -41,6 +43,9 @@ public class CRaterController {
4143
@Autowired
4244
private CRaterService cRaterService;
4345

46+
@Autowired
47+
private CRaterPingService cRaterPingService;
48+
4449
@GetMapping("/verify")
4550
String verifyItemId(CRaterVerificationRequest request) throws JSONException {
4651
return cRaterService.getCRaterResponse(request);
@@ -50,4 +55,14 @@ String verifyItemId(CRaterVerificationRequest request) throws JSONException {
5055
String scoreItem(@RequestBody CRaterScoringRequest request) throws JSONException {
5156
return cRaterService.getCRaterResponse(request);
5257
}
58+
59+
@PostMapping("/ping")
60+
public String pingItem(@RequestBody CRaterPingRequest ping) throws JSONException {
61+
String itemId = ping.getItemId();
62+
if (!this.cRaterPingService.hasPingedItem(itemId)) {
63+
this.cRaterPingService.cachePingedItem(itemId, 280);
64+
return this.cRaterService.getCRaterResponse(ping);
65+
}
66+
return "";
67+
}
5368
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.wise.portal.service.ping.impl;
2+
3+
import static org.easymock.EasyMock.expect;
4+
import static org.easymock.EasyMock.replay;
5+
import static org.easymock.EasyMock.verify;
6+
import static org.junit.Assert.assertFalse;
7+
import static org.junit.Assert.assertTrue;
8+
9+
import java.time.Duration;
10+
import org.easymock.EasyMockExtension;
11+
import org.easymock.Mock;
12+
import org.easymock.TestSubject;
13+
import org.junit.jupiter.api.Test;
14+
import org.junit.jupiter.api.extension.ExtendWith;
15+
import org.springframework.data.redis.core.StringRedisTemplate;
16+
import org.springframework.data.redis.core.ValueOperations;
17+
18+
@ExtendWith(EasyMockExtension.class)
19+
public class CRaterPingServiceImplTest {
20+
@TestSubject
21+
private CRaterPingServiceImpl cRaterPingServiceImpl = new CRaterPingServiceImpl();
22+
23+
@Mock
24+
private StringRedisTemplate stringRedisTemplate;
25+
26+
@Mock
27+
private ValueOperations<String, String> valueOperations;
28+
29+
private String testId = "test";
30+
31+
@Test
32+
public void hasPingedItem_ItemPinged_ShouldReturnTrue() {
33+
expect(stringRedisTemplate.opsForValue()).andReturn(valueOperations);
34+
expect(valueOperations.size(testId)).andReturn(1L);
35+
replay(stringRedisTemplate, valueOperations);
36+
assertTrue(cRaterPingServiceImpl.hasPingedItem(testId));
37+
verify(stringRedisTemplate);
38+
verify(valueOperations);
39+
}
40+
41+
@Test
42+
public void hasPingedItem_ItemNotPinged_ShouldReturnFalse() {
43+
expect(stringRedisTemplate.opsForValue()).andReturn(valueOperations);
44+
expect(valueOperations.size(testId)).andReturn(0L);
45+
replay(stringRedisTemplate, valueOperations);
46+
assertFalse(cRaterPingServiceImpl.hasPingedItem(testId));
47+
verify(stringRedisTemplate);
48+
verify(valueOperations);
49+
50+
}
51+
52+
@Test
53+
public void cachePingedItem_ShouldCacheAndExpireItemId() {
54+
expect(stringRedisTemplate.opsForValue()).andReturn(valueOperations);
55+
expect(stringRedisTemplate.expire(testId, Duration.ofSeconds(1))).andReturn(null);
56+
expect(valueOperations.setIfAbsent(testId, "pinged")).andReturn(null);
57+
replay(stringRedisTemplate, valueOperations);
58+
cRaterPingServiceImpl.cachePingedItem(testId, 1);
59+
verify(stringRedisTemplate, valueOperations);
60+
}
61+
}

src/test/java/org/wise/vle/web/CRaterControllerTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.wise.vle.web;
22

3+
import static junit.framework.TestCase.assertEquals;
34
import static org.easymock.EasyMock.*;
5+
import static org.junit.Assert.assertNotEquals;
46
import static org.junit.Assert.assertNotNull;
57

68
import org.easymock.EasyMockExtension;
@@ -9,6 +11,8 @@
911
import org.json.JSONException;
1012
import org.junit.jupiter.api.Test;
1113
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.wise.portal.service.ping.CRaterPingService;
15+
import org.wise.vle.domain.webservice.crater.CRaterPingRequest;
1216
import org.wise.vle.domain.webservice.crater.CRaterScoringRequest;
1317
import org.wise.vle.domain.webservice.crater.CRaterService;
1418
import org.wise.vle.domain.webservice.crater.CRaterVerificationRequest;
@@ -22,8 +26,12 @@ public class CRaterControllerTest {
2226
@Mock
2327
private CRaterService cRaterService;
2428

29+
@Mock
30+
private CRaterPingService cRaterPingService;
31+
2532
private String clientId = "wise-test";
2633
private String itemId = "test-item-id";
34+
private String berkeleyItemId = "berkeley_test-item-id";
2735
private Long trackingId = 123456789L;
2836

2937
@Test
@@ -80,4 +88,51 @@ private String createScoringResponseString(String itemId, Long trackingId, Strin
8088
responseBuffer.append("}");
8189
return responseBuffer.toString();
8290
}
91+
92+
@Test
93+
public void pingItem_ItemAlreadyPinged_ShouldReturnEmpty() {
94+
CRaterPingRequest request = new CRaterPingRequest();
95+
request.setItemId(berkeleyItemId);
96+
try {
97+
expect(cRaterPingService.hasPingedItem(berkeleyItemId)).andReturn(true);
98+
replay(cRaterService, cRaterPingService);
99+
String response = controller.pingItem(request);
100+
assertEquals(response, "");
101+
verify(cRaterService, cRaterPingService);
102+
} catch (JSONException exception) {
103+
104+
}
105+
}
106+
107+
@Test
108+
public void pingItem_ItemNotPinged_ShouldReturnString() {
109+
CRaterPingRequest request = new CRaterPingRequest();
110+
request.setItemId(berkeleyItemId);
111+
try {
112+
expect(cRaterService.getCRaterResponse(request))
113+
.andReturn(createPingResponseString(berkeleyItemId, trackingId, clientId));
114+
expect(cRaterPingService.hasPingedItem(berkeleyItemId)).andReturn(false);
115+
cRaterPingService.cachePingedItem(berkeleyItemId, 280);
116+
expectLastCall();
117+
replay(cRaterService, cRaterPingService);
118+
String response = controller.pingItem(request);
119+
assertNotNull(response);
120+
assertNotEquals(response, "");
121+
verify(cRaterService, cRaterPingService);
122+
} catch (JSONException exception) {
123+
124+
}
125+
126+
}
127+
128+
private String createPingResponseString(String itemId, Long trackingId, String clientId) {
129+
StringBuffer responseBuffer = new StringBuffer();
130+
responseBuffer.append("{");
131+
responseBuffer.append(" \"item_id\": \"" + itemId + "\",");
132+
responseBuffer.append(" \"success\": true,");
133+
responseBuffer.append(" \"tracking_id\": " + trackingId + ",");
134+
responseBuffer.append(" \"client_id\": \"" + clientId + "\"");
135+
responseBuffer.append("}");
136+
return responseBuffer.toString();
137+
}
83138
}

0 commit comments

Comments
 (0)