diff --git a/pom.xml b/pom.xml
index 51ed1891e..3caacb9c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -452,11 +452,6 @@
HikariCP
7.1.0
-
- org.apache.httpcomponents
- httpclient
- 4.5.14
-
org.apache.commons
commons-lang3
diff --git a/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java b/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java
index ee1a73886..cb8645e75 100644
--- a/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java
+++ b/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java
@@ -23,7 +23,6 @@
*/
package org.wise.portal.domain.admin;
-import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
@@ -35,14 +34,12 @@
import jakarta.mail.MessagingException;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.client.RestClientException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -52,7 +49,6 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
-import org.wise.portal.dao.ObjectNotFoundException;
import org.wise.portal.dao.run.RunDao;
import org.wise.portal.dao.portal.PortalStatisticsDao;
import org.wise.portal.dao.project.ProjectDao;
@@ -60,7 +56,6 @@
import org.wise.portal.domain.authentication.MutableUserDetails;
import org.wise.portal.domain.authentication.impl.StudentUserDetails;
import org.wise.portal.domain.authentication.impl.TeacherUserDetails;
-import org.wise.portal.domain.portal.Portal;
import org.wise.portal.domain.portal.PortalStatistics;
import org.wise.portal.domain.portal.impl.PortalStatisticsImpl;
import org.wise.portal.domain.project.Project;
@@ -526,24 +521,19 @@ public void sendEmail(String message) {
public void postStatistics(String wiseStatisticsString) {
if (WISE_HUB_URL != null) {
- HttpClient client = HttpClientBuilder.create().build();
- HttpPost post = new HttpPost(WISE_HUB_URL);
- List urlParameters = new ArrayList();
- urlParameters.add(new BasicNameValuePair("name", appProperties.getProperty("wise.name")));
- urlParameters.add(new BasicNameValuePair("stats", wiseStatisticsString));
+ MultiValueMap formData = new LinkedMultiValueMap<>();
+ formData.add("name", appProperties.getProperty("wise.name"));
+ formData.add("stats", wiseStatisticsString);
try {
- post.setEntity(new UrlEncodedFormEntity(urlParameters));
- HttpResponse response = client.execute(post);
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- System.err.println("Method failed: " + response.getStatusLine());
- }
- // Use caution: ensure correct character encoding and is not binary data
- } catch (IOException e) {
+ RestClient restClient = RestClient.create();
+ restClient.post().uri(WISE_HUB_URL).contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .body(formData).retrieve().onStatus(HttpStatusCode::isError, (request, response) -> {
+ System.err.println("Method failed: " + response.getStatusCode());
+ }).toBodilessEntity();
+ } catch (RestClientException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
- } finally {
- post.releaseConnection();
}
}
}
diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/contact/ContactAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/contact/ContactAPIController.java
index 01458cc93..64706094c 100644
--- a/src/main/java/org/wise/portal/presentation/web/controllers/contact/ContactAPIController.java
+++ b/src/main/java/org/wise/portal/presentation/web/controllers/contact/ContactAPIController.java
@@ -1,12 +1,10 @@
package org.wise.portal.presentation.web.controllers.contact;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
+import org.springframework.http.MediaType;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.client.RestClientException;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,13 +26,8 @@
import org.wise.portal.service.user.UserService;
import jakarta.mail.MessagingException;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Properties;
@RestController
@@ -297,8 +290,7 @@ private boolean appPropertiesHasUserAgentParseKey() {
}
private JSONObject getUserAgentParseResult(String userAgent) throws IOException, JSONException {
- HttpPost post = prepareUserAgentParseRequest(userAgent);
- JSONObject userAgentResponse = makeUserAgentParseRequest(post);
+ JSONObject userAgentResponse = makeUserAgentParseRequest(userAgent);
if (isUserAgentResponseSuccess(userAgentResponse)) {
JSONObject parse = userAgentResponse.getJSONObject("parse");
return parse;
@@ -306,33 +298,28 @@ private JSONObject getUserAgentParseResult(String userAgent) throws IOException,
return null;
}
- private HttpPost prepareUserAgentParseRequest(String userAgent) {
+ private JSONObject makeUserAgentParseRequest(String userAgent) throws IOException, JSONException {
String userKey = appProperties.getProperty("userAgentParseKey");
- HttpPost post = new HttpPost(userAgentParseURL);
- List urlParameters = new ArrayList();
- urlParameters.add(new BasicNameValuePair("user_key", userKey));
- urlParameters.add(new BasicNameValuePair("user_agent", userAgent));
- try {
- post.setEntity(new UrlEncodedFormEntity(urlParameters));
- } catch (UnsupportedEncodingException e) {
-
- }
- return post;
- }
+ MultiValueMap formData = new LinkedMultiValueMap<>();
+ formData.add("user_key", userKey);
+ formData.add("user_agent", userAgent);
- private JSONObject makeUserAgentParseRequest(HttpPost post) throws IOException, JSONException {
- HttpClient client = HttpClientBuilder.create().build();
- HttpResponse response = client.execute(post);
- BufferedReader rd = new BufferedReader(
- new InputStreamReader(response.getEntity().getContent()));
- StringBuffer userAgentParseResult = new StringBuffer();
- String line = "";
- while ((line = rd.readLine()) != null) {
- userAgentParseResult.append(line);
+ RestClient restClient = RestClient.create();
+ try {
+ String responseBody = restClient.post()
+ .uri(userAgentParseURL)
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .body(formData)
+ .retrieve()
+ .body(String.class);
+
+ if (responseBody != null) {
+ return new JSONObject(responseBody);
+ }
+ } catch (RestClientException e) {
+ throw new IOException("Failed to parse user agent", e);
}
- String parseResultString = userAgentParseResult.toString();
- JSONObject parseResultJSONObject = new JSONObject(parseResultString);
- return parseResultJSONObject;
+ return null;
}
private boolean isUserAgentResponseSuccess(JSONObject userAgentResponse) {
diff --git a/src/main/java/org/wise/vle/domain/webservice/crater/CRaterService.java b/src/main/java/org/wise/vle/domain/webservice/crater/CRaterService.java
index 4a94c1712..cbb60f69e 100644
--- a/src/main/java/org/wise/vle/domain/webservice/crater/CRaterService.java
+++ b/src/main/java/org/wise/vle/domain/webservice/crater/CRaterService.java
@@ -23,18 +23,10 @@
*/
package org.wise.vle.domain.webservice.crater;
-import java.io.IOException;
-import java.util.Base64;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.HttpClientBuilder;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.client.RestClientException;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
@@ -49,8 +41,14 @@
@Service
public class CRaterService {
+ private final Environment appProperties;
+ private final RestClient restClient;
+
@Autowired
- private Environment appProperties;
+ public CRaterService(Environment appProperties, RestClient.Builder restClientBuilder) {
+ this.appProperties = appProperties;
+ this.restClient = restClientBuilder.build();
+ }
/**
* Sends either student work (scoring request) or an item id (verification request) to
@@ -78,26 +76,18 @@ public String getCRaterResponse(CRaterRequest request) throws JSONException {
* @return the response string from the CRater server
*/
private String post(CRaterRequest request) throws JSONException {
- HttpClient client = HttpClientBuilder.create().build();
- HttpPost post = new HttpPost(request.getCRaterUrl());
try {
String password = appProperties.getProperty(
request.forBerkeleyEndpoint() ? "berkeley_cRater_password" : "cRater_password");
- String authHeader = "Basic "
- + Base64.getEncoder().encodeToString(("extsyscrtr02dev:" + password).getBytes());
- post.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
- post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8");
- post.setEntity(new StringEntity(request.generateBodyData(), ContentType.APPLICATION_JSON));
- HttpResponse response = client.execute(post);
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- System.err.println("Method failed: " + response.getStatusLine());
- }
- return IOUtils.toString(response.getEntity().getContent(), "UTF-8");
- } catch (IOException e) {
+ return restClient.post().uri(request.getCRaterUrl())
+ .headers(headers -> headers.setBasicAuth("extsyscrtr02dev", password))
+ .contentType(MediaType.APPLICATION_JSON_UTF8).body(request.generateBodyData()).retrieve()
+ .onStatus(HttpStatusCode::isError, (req, resp) -> {
+ System.err.println("Method failed: " + resp.getStatusCode());
+ }).body(String.class);
+ } catch (RestClientException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
- } finally {
- post.releaseConnection();
}
return null;
}
diff --git a/src/test/java/org/wise/vle/domain/webservice/crater/CRaterServiceTest.java b/src/test/java/org/wise/vle/domain/webservice/crater/CRaterServiceTest.java
index 67abab653..ec7bdcf81 100644
--- a/src/test/java/org/wise/vle/domain/webservice/crater/CRaterServiceTest.java
+++ b/src/test/java/org/wise/vle/domain/webservice/crater/CRaterServiceTest.java
@@ -1,24 +1,32 @@
package org.wise.vle.domain.webservice.crater;
import static org.easymock.EasyMock.*;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
import org.easymock.EasyMockExtension;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.json.JSONException;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.core.env.Environment;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestClient;
@ExtendWith(EasyMockExtension.class)
public class CRaterServiceTest {
- @TestSubject
- private CRaterService cRaterService = new CRaterService();
+ private CRaterService cRaterService;
@Mock
private Environment appProperties;
+ private MockRestServiceServer mockServer;
+
private String clientId = "wise-test";
private String itemId = "test-item-id";
private String password = "abc123";
@@ -27,6 +35,13 @@ public class CRaterServiceTest {
private String berkeleyScoringUrl = "https://test.org/score/berkeley";
private String berkeleyVerifyUrl = "https://test.org/verify/berkeley";
+ @BeforeEach
+ public void setUp() {
+ RestClient.Builder builder = RestClient.builder();
+ mockServer = MockRestServiceServer.bindTo(builder).build();
+ cRaterService = new CRaterService(appProperties, builder);
+ }
+
public void beforeETS() {
expect(appProperties.getProperty("cRater_client_id")).andReturn(clientId);
expect(appProperties.getProperty("cRater_password")).andReturn(password);
@@ -46,8 +61,11 @@ public void getScoringResponse_ShouldGetCRaterProperties() throws JSONException
request.setResponseText("hello");
expect(appProperties.getProperty("cRater_scoring_url")).andReturn(scoringUrl);
replay(appProperties);
+ mockServer.expect(requestTo(scoringUrl)).andExpect(method(HttpMethod.POST))
+ .andRespond(withSuccess("{}", MediaType.APPLICATION_JSON));
cRaterService.getCRaterResponse(request);
verify(appProperties);
+ mockServer.verify();
}
@Test
@@ -57,8 +75,11 @@ public void getVerificationResponse_ShouldGetCRaterProperties() throws JSONExcep
request.setItemId(itemId);
expect(appProperties.getProperty("cRater_verification_url")).andReturn(verifyUrl);
replay(appProperties);
+ mockServer.expect(requestTo(verifyUrl)).andExpect(method(HttpMethod.POST))
+ .andRespond(withSuccess("{}", MediaType.APPLICATION_JSON));
cRaterService.getCRaterResponse(request);
verify(appProperties);
+ mockServer.verify();
}
@Test
@@ -70,8 +91,11 @@ public void getBerkeleyScoringResponse_ShouldGetCRaterProperties() throws JSONEx
request.setResponseText("hello");
expect(appProperties.getProperty("berkeley_cRater_scoring_url")).andReturn(berkeleyScoringUrl);
replay(appProperties);
+ mockServer.expect(requestTo(berkeleyScoringUrl)).andExpect(method(HttpMethod.POST))
+ .andRespond(withSuccess("{}", MediaType.APPLICATION_JSON));
cRaterService.getCRaterResponse(request);
verify(appProperties);
+ mockServer.verify();
}
@Test
@@ -82,7 +106,10 @@ public void getBerkeleyVerificationResponse_ShouldGetCRaterProperties() throws J
expect(appProperties.getProperty("berkeley_cRater_verification_url"))
.andReturn(berkeleyVerifyUrl);
replay(appProperties);
+ mockServer.expect(requestTo(berkeleyVerifyUrl)).andExpect(method(HttpMethod.POST))
+ .andRespond(withSuccess("{}", MediaType.APPLICATION_JSON));
cRaterService.getCRaterResponse(request);
verify(appProperties);
+ mockServer.verify();
}
}