diff --git a/pom.xml b/pom.xml
index d5bc245..ec11f6f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
com.github.wnameless.spring
spring-bulk-api
- 0.7.1-SNAPSHOT
+ 0.7.4.1-SNAPSHOT
spring-bulk-api
Add bulk operations support to any Spring RESTful API by a single annotation @EnableBulkApi.
@@ -109,6 +109,19 @@
gson
test
+
+ org.projectlombok
+ lombok
+ 1.18.12
+ test
+
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1
+
+
diff --git a/src/main/java/com/github/wnameless/spring/bulkapi/BulkApiController.java b/src/main/java/com/github/wnameless/spring/bulkapi/BulkApiController.java
index 6e2ea39..4837a20 100644
--- a/src/main/java/com/github/wnameless/spring/bulkapi/BulkApiController.java
+++ b/src/main/java/com/github/wnameless/spring/bulkapi/BulkApiController.java
@@ -23,6 +23,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
+import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -60,6 +61,7 @@ private BulkApiService bulkApiService() {
* @throws BulkApiException
* if this bulk request is invalid
*/
+ @CrossOrigin("*")
@RequestMapping(value = "${spring.bulk.api.path:/bulk}", method = POST)
BulkResponse bulk(@RequestBody BulkRequest req, HttpServletRequest servReq) {
return bulkApiService().bulk(req, servReq);
diff --git a/src/main/java/com/github/wnameless/spring/bulkapi/BulkOperation.java b/src/main/java/com/github/wnameless/spring/bulkapi/BulkOperation.java
index 0aef0e5..105e13f 100644
--- a/src/main/java/com/github/wnameless/spring/bulkapi/BulkOperation.java
+++ b/src/main/java/com/github/wnameless/spring/bulkapi/BulkOperation.java
@@ -32,6 +32,7 @@ public final class BulkOperation {
private Map params = new LinkedHashMap();
private Map headers = new LinkedHashMap();
private boolean silent = false;
+ private String payload;
/**
* Returns the URL of this RESTful operation.
@@ -128,6 +129,26 @@ public void setSilent(boolean silent) {
this.silent = silent;
}
+ /**
+ * Returns payload which client put in request without any change
+ * In addition to using the order of results, client can put a string or number to distinguish between returned results.
+ *
+ * @return payload of a RESTful operation
+ */
+ public String getPayload() {
+ return payload;
+ }
+
+ /**
+ * Sets the payload parameters of this RESTful operation.
+ *
+ * @param payload
+ * an arbitrary string
+ */
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+
@Override
public int hashCode() {
int result = 27;
diff --git a/src/main/java/com/github/wnameless/spring/bulkapi/BulkResult.java b/src/main/java/com/github/wnameless/spring/bulkapi/BulkResult.java
index 69302c7..f5ca4ee 100644
--- a/src/main/java/com/github/wnameless/spring/bulkapi/BulkResult.java
+++ b/src/main/java/com/github/wnameless/spring/bulkapi/BulkResult.java
@@ -17,6 +17,7 @@
*/
package com.github.wnameless.spring.bulkapi;
+import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.Map;
/**
@@ -29,6 +30,8 @@ public final class BulkResult {
private int status;
private String body;
private Map headers;
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private String payload;
/**
* Returns the HTTP status code of a RESTful operation outcome.
@@ -87,6 +90,26 @@ public void setHeaders(Map headers) {
this.headers = headers;
}
+ /**
+ * Returns payload which client put in request without any change
+ * Client can put a string or number to distinguish between returned results
+ *
+ * @return payload of a RESTful operation
+ */
+ public String getPayload() {
+ return payload;
+ }
+
+ /**
+ * Sets the payload parameters of this RESTful operation.
+ *
+ * @param payload
+ * an arbitrary string
+ */
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+
@Override
public int hashCode() {
int result = 27;
diff --git a/src/main/java/com/github/wnameless/spring/bulkapi/DefaultBulkApiService.java b/src/main/java/com/github/wnameless/spring/bulkapi/DefaultBulkApiService.java
index 1b577c6..0857045 100755
--- a/src/main/java/com/github/wnameless/spring/bulkapi/DefaultBulkApiService.java
+++ b/src/main/java/com/github/wnameless/spring/bulkapi/DefaultBulkApiService.java
@@ -17,180 +17,203 @@
*/
package com.github.wnameless.spring.bulkapi;
-import static com.github.wnameless.spring.bulkapi.BulkApiConfig.BULK_API_LIMIT_DEFAULT;
-import static com.github.wnameless.spring.bulkapi.BulkApiConfig.BULK_API_LIMIT_KEY;
-import static com.github.wnameless.spring.bulkapi.BulkApiConfig.BULK_API_PATH_DEFAULT;
-import static com.github.wnameless.spring.bulkapi.BulkApiConfig.BULK_API_PATH_KEY;
-import static org.springframework.http.HttpStatus.PAYLOAD_TOO_LARGE;
-import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map.Entry;
-
-import javax.servlet.http.HttpServletRequest;
-
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.RequestEntity.BodyBuilder;
import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
+import javax.servlet.http.HttpServletRequest;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import static com.github.wnameless.spring.bulkapi.BulkApiConfig.*;
+import static org.springframework.http.HttpStatus.*;
+
/**
- *
* {@link DefaultBulkApiService} id the default implementation of
* {@link BulkApiService}.
- *
*/
public class DefaultBulkApiService implements BulkApiService {
- private final ApplicationContext appCtx;
- private final Environment env;
-
- private BulkApiValidator validator;
- private URITransformer uriTransformer;
-
- /**
- * Creates a {@link DefaultBulkApiService}.
- *
- * @param appCtx
- * the Spring {@link ApplicationContext}
- */
- public DefaultBulkApiService(ApplicationContext appCtx) {
- this.appCtx = appCtx;
- env = appCtx.getEnvironment();
-
- String[] beanNames = appCtx.getBeanNamesForType(URITransformer.class);
- if (beanNames.length > 0) {
- uriTransformer = appCtx.getBean(URITransformer.class);
+ private final ApplicationContext appCtx;
+ private final Environment env;
+
+ private BulkApiValidator validator;
+ private URITransformer uriTransformer;
+
+ /**
+ * Creates a {@link DefaultBulkApiService}.
+ *
+ * @param appCtx the Spring {@link ApplicationContext}
+ */
+ public DefaultBulkApiService(ApplicationContext appCtx) {
+ this.appCtx = appCtx;
+ env = appCtx.getEnvironment();
+
+ String[] beanNames = appCtx.getBeanNamesForType(URITransformer.class);
+ if (beanNames.length > 0) {
+ uriTransformer = appCtx.getBean(URITransformer.class);
+ }
}
- }
- private BulkApiValidator validator() {
- if (validator == null) validator = new BulkApiValidator(appCtx);
- return validator;
- }
+ private BulkApiValidator validator() {
+ if (validator == null) validator = new BulkApiValidator(appCtx);
+ return validator;
+ }
- @Override
- public BulkResponse bulk(BulkRequest req, HttpServletRequest servReq) {
- validateBulkRequest(req, servReq);
+ @Override
+ public BulkResponse bulk(BulkRequest req, HttpServletRequest servReq) {
+ validateBulkRequest(req, servReq);
- List results = new ArrayList<>();
- RestTemplate template = new RestTemplate();
- for (BulkOperation op : req.getOperations()) {
- ComputedURIResult uriResult = computeUri(servReq, op);
+ List results = new ArrayList<>();
+ RestTemplate template = new RestTemplate();
+ template.setErrorHandler(new MyErrorHandler());
+ for (BulkOperation op : req.getOperations()) {
+ ComputedURIResult uriResult = computeUri(servReq, op);
- BodyBuilder bodyBuilder = RequestEntity.method(//
- httpMethod(op.getMethod()), uriResult.getUri());
+ BodyBuilder bodyBuilder = RequestEntity.method(//
+ httpMethod(op.getMethod()), uriResult.getUri());
- ResponseEntity rawRes = template.exchange(
- requestEntity(bodyBuilder, op, uriResult.hasRequestBody()),
- String.class);
+ ResponseEntity rawRes = null;
+ try {
+ rawRes = template.exchange(
+ requestEntity(bodyBuilder, op, uriResult.hasRequestBody()),
+ String.class);
+ } catch (ResourceAccessException e) {
+ if (e.getCause().getMessage().equals("cannot retry due to server authentication, in streaming mode")) {
+ throw new BulkApiException(UNAUTHORIZED, e.getMessage());
+ }
- if (!op.isSilent()) results.add(buildResult(rawRes));
- }
+ }
+
+ if (!op.isSilent()) results.add(buildResult(rawRes, op.getPayload()));
+ }
- return new BulkResponse(results);
- }
+ return new BulkResponse(results);
+ }
- private RequestEntity> requestEntity(BodyBuilder bodyBuilder,
- BulkOperation op, boolean requestBody) {
- for (Entry header : op.getHeaders().entrySet()) {
- bodyBuilder.header(header.getKey(), header.getValue());
+ private RequestEntity> requestEntity(BodyBuilder bodyBuilder,
+ BulkOperation op, boolean requestBody) {
+ for (Entry header : op.getHeaders().entrySet()) {
+ bodyBuilder.header(header.getKey(), header.getValue());
+ }
+
+ Object params;
+ if (requestBody) {
+ params = op.getParams();
+ } else {
+ LinkedMultiValueMap lmvm = new LinkedMultiValueMap<>();
+ lmvm.setAll(op.getParams());
+ params = lmvm;
+ }
+
+ return bodyBuilder.body(params);
}
- Object params;
- if (requestBody) {
- params = op.getParams();
- } else {
- LinkedMultiValueMap lmvm = new LinkedMultiValueMap<>();
- lmvm.setAll(op.getParams());
- params = lmvm;
+ private ComputedURIResult computeUri(HttpServletRequest servReq,
+ BulkOperation op) {
+ String rawUrl = servReq.getRequestURL().toString();
+ String rawUri = servReq.getRequestURI().toString();
+
+ if (op.getUrl() == null || isBulkPath(op.getUrl())) {
+ throw new BulkApiException(UNPROCESSABLE_ENTITY,
+ "Invalid URL(" + rawUri + ") exists in this bulk request");
+ }
+
+ String bulkPath =
+ urlify(env.getProperty(BULK_API_PATH_KEY, BULK_API_PATH_DEFAULT));
+ URI uri;
+ try {
+ String servletPath = rawUrl.substring(0, rawUrl.lastIndexOf(bulkPath));
+ uri = new URI(servletPath + urlify(op.getUrl()));
+ } catch (URISyntaxException e) {
+ throw new BulkApiException(UNPROCESSABLE_ENTITY, "Invalid URL("
+ + urlify(op.getUrl()) + ") exists in this bulk request");
+ }
+
+ PathValidationResult pvr = validator().validatePath(stripeQueryParam(urlify(op.getUrl())),
+ httpMethod(op.getMethod()));
+ if (!pvr.isValid()) {
+ throw new BulkApiException(UNPROCESSABLE_ENTITY, "Invalid URL("
+ + urlify(op.getUrl()) + ") exists in this bulk request");
+ }
+
+ if (uriTransformer != null) uri = uriTransformer.transform(uri);
+ return new ComputedURIResult(uri, pvr.hasRequestBody());
}
- return bodyBuilder.body(params);
- }
+ private boolean isBulkPath(String url) {
+ String bulkPath =
+ urlify(env.getProperty(BULK_API_PATH_KEY, BULK_API_PATH_DEFAULT));
+ url = urlify(url);
- private ComputedURIResult computeUri(HttpServletRequest servReq,
- BulkOperation op) {
- String rawUrl = servReq.getRequestURL().toString();
- String rawUri = servReq.getRequestURI().toString();
+ return url.equals(bulkPath) || url.startsWith(bulkPath + "/");
+ }
- if (op.getUrl() == null || isBulkPath(op.getUrl())) {
- throw new BulkApiException(UNPROCESSABLE_ENTITY,
- "Invalid URL(" + rawUri + ") exists in this bulk request");
+ private String urlify(String url) {
+ url = url.trim();
+ return url.startsWith("/") ? url : "/" + url;
}
- String bulkPath =
- urlify(env.getProperty(BULK_API_PATH_KEY, BULK_API_PATH_DEFAULT));
- URI uri;
- try {
- String servletPath = rawUrl.substring(0, rawUrl.lastIndexOf(bulkPath));
- uri = new URI(servletPath + urlify(op.getUrl()));
- } catch (URISyntaxException e) {
- throw new BulkApiException(UNPROCESSABLE_ENTITY, "Invalid URL("
- + urlify(op.getUrl()) + ") exists in this bulk request");
+ private String stripeQueryParam(String url) {
+ return url.split("\\?")[0];
}
- PathValidationResult pvr = validator().validatePath(urlify(op.getUrl()),
- httpMethod(op.getMethod()));
- if (!pvr.isValid()) {
- throw new BulkApiException(UNPROCESSABLE_ENTITY, "Invalid URL("
- + urlify(op.getUrl()) + ") exists in this bulk request");
+ private BulkResult buildResult(ResponseEntity rawRes, String payload) {
+ BulkResult res = new BulkResult();
+ res.setStatus(rawRes.getStatusCodeValue());
+ res.setHeaders(rawRes.getHeaders().toSingleValueMap());
+ res.setBody(rawRes.getBody());
+ res.setPayload(payload);
+
+ return res;
}
- if (uriTransformer != null) uri = uriTransformer.transform(uri);
- return new ComputedURIResult(uri, pvr.hasRequestBody());
- }
-
- private boolean isBulkPath(String url) {
- String bulkPath =
- urlify(env.getProperty(BULK_API_PATH_KEY, BULK_API_PATH_DEFAULT));
- url = urlify(url);
-
- return url.equals(bulkPath) || url.startsWith(bulkPath + "/");
- }
-
- private String urlify(String url) {
- url = url.trim();
- return url.startsWith("/") ? url : "/" + url;
- }
-
- private BulkResult buildResult(ResponseEntity rawRes) {
- BulkResult res = new BulkResult();
- res.setStatus(rawRes.getStatusCodeValue());
- res.setHeaders(rawRes.getHeaders().toSingleValueMap());
- res.setBody(rawRes.getBody());
-
- return res;
- }
-
- private void validateBulkRequest(BulkRequest req,
- HttpServletRequest servReq) {
- int max =
- env.getProperty(BULK_API_LIMIT_KEY, int.class, BULK_API_LIMIT_DEFAULT);
- if (req.getOperations().size() > max) {
- throw new BulkApiException(PAYLOAD_TOO_LARGE,
- "Bulk operations exceed the limitation(" + max + ")");
+ private void validateBulkRequest(BulkRequest req,
+ HttpServletRequest servReq) {
+ int max =
+ env.getProperty(BULK_API_LIMIT_KEY, int.class, BULK_API_LIMIT_DEFAULT);
+ if (req.getOperations().size() > max) {
+ throw new BulkApiException(PAYLOAD_TOO_LARGE,
+ "Bulk operations exceed the limitation(" + max + ")");
+ }
+
+ // Check if any invalid URL exists
+ for (BulkOperation op : req.getOperations()) {
+ computeUri(servReq, op);
+ }
}
- // Check if any invalid URL exists
- for (BulkOperation op : req.getOperations()) {
- computeUri(servReq, op);
+ private static HttpMethod httpMethod(String method) {
+ try {
+ return HttpMethod.valueOf(method.toUpperCase());
+ } catch (Exception e) {
+ return HttpMethod.GET;
+ }
}
- }
- private static HttpMethod httpMethod(String method) {
- try {
- return HttpMethod.valueOf(method.toUpperCase());
- } catch (Exception e) {
- return HttpMethod.GET;
+}
+
+
+//This Handler created just to avoid showing error for whole operation and show error for the specific url
+class MyErrorHandler implements ResponseErrorHandler {
+
+ @Override
+ public void handleError(ClientHttpResponse clientHttpResponse) {
}
- }
+ @Override
+ public boolean hasError(ClientHttpResponse clientHttpResponse) {
+ return false;
+ }
}
diff --git a/src/test/java/com/github/wnameless/spring/bulkapi/test/BulkApiTest.java b/src/test/java/com/github/wnameless/spring/bulkapi/test/BulkApiTest.java
index d669aab..0e43c69 100644
--- a/src/test/java/com/github/wnameless/spring/bulkapi/test/BulkApiTest.java
+++ b/src/test/java/com/github/wnameless/spring/bulkapi/test/BulkApiTest.java
@@ -17,24 +17,28 @@
*/
package com.github.wnameless.spring.bulkapi.test;
-import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor;
-import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanToStringExcluding;
-import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters;
-import static org.hamcrest.CoreMatchers.allOf;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-import java.util.Map;
-
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.wnameless.spring.bulkapi.BulkOperation;
+import com.github.wnameless.spring.bulkapi.BulkRequest;
+import com.github.wnameless.spring.bulkapi.BulkResponse;
+import com.github.wnameless.spring.bulkapi.BulkResult;
+import com.github.wnameless.spring.bulkapi.test.AppConfig.TestURITransformer;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import net.sf.rubycollect4j.Ruby;
+import nl.jqno.equalsverifier.EqualsVerifier;
+import nl.jqno.equalsverifier.Warning;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,305 +51,333 @@
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Base64Utils;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.wnameless.spring.bulkapi.BulkOperation;
-import com.github.wnameless.spring.bulkapi.BulkRequest;
-import com.github.wnameless.spring.bulkapi.BulkResponse;
-import com.github.wnameless.spring.bulkapi.BulkResult;
-import com.github.wnameless.spring.bulkapi.test.AppConfig.TestURITransformer;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
+import java.util.HashMap;
+import java.util.Map;
-import net.sf.rubycollect4j.Ruby;
-import nl.jqno.equalsverifier.EqualsVerifier;
-import nl.jqno.equalsverifier.Warning;
+import static com.google.code.beanmatchers.BeanMatchers.*;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class,
- webEnvironment = WebEnvironment.RANDOM_PORT)
+ webEnvironment = WebEnvironment.RANDOM_PORT)
public class BulkApiTest {
- @LocalServerPort
- int port;
+ @LocalServerPort
+ int port;
+
+ @Value("${spring.bulk.api.path:/bulk}")
+ String bulkPath;
+
+ HttpClient client = HttpClientBuilder.create().build();
+ HttpPost post;
+
+ ObjectMapper mapper = new ObjectMapper();
- @Value("${spring.bulk.api.path:/bulk}")
- String bulkPath;
+ @Autowired
+ ApplicationContext appCtx;
- HttpClient client = HttpClientBuilder.create().build();
- HttpPost post;
+ String authHeader =
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes());
- ObjectMapper mapper = new ObjectMapper();
+ @Autowired
+ TestURITransformer testUriTransformer;
- @Autowired
- ApplicationContext appCtx;
+ @Before
+ public void setUp() {
+ post = new HttpPost("http://localhost:" + port + bulkPath);
+ post.setHeader("Content-Type", "application/json");
+ }
+
+ @Test
+ public void testBeans() throws Exception {
+ assertThat(BulkOperation.class, allOf(hasValidBeanConstructor(),
+ hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
+ EqualsVerifier.forClass(BulkOperation.class)
+ .suppress(Warning.NONFINAL_FIELDS).verify();
+
+ assertThat(BulkRequest.class, allOf(hasValidBeanConstructor(),
+ hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
+ EqualsVerifier.forClass(BulkRequest.class).suppress(Warning.NONFINAL_FIELDS)
+ .verify();
+
+ assertThat(BulkResponse.class, allOf(hasValidBeanConstructor(),
+ hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
+ EqualsVerifier.forClass(BulkResponse.class)
+ .suppress(Warning.NONFINAL_FIELDS).verify();
+
+ assertThat(BulkResult.class, allOf(hasValidBeanConstructor(),
+ hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
+ EqualsVerifier.forClass(BulkResult.class).suppress(Warning.NONFINAL_FIELDS)
+ .verify();
+ }
- String authHeader =
- "Basic " + Base64Utils.encodeToString("user:password".getBytes());
+ private BulkRequest operationTimes(int times) {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
- @Autowired
- TestURITransformer testUriTransformer;
+ times--;
- @Before
- public void setUp() {
- post = new HttpPost("http://localhost:" + port + bulkPath);
- post.setHeader("Content-Type", "application/json");
- }
+ op.setMethod("GET");
+ op.setUrl("home");
+ op.getHeaders().put("Authorization", authHeader);
+ req.getOperations().add(op);
- @Test
- public void testBeans() throws Exception {
- assertThat(BulkOperation.class, allOf(hasValidBeanConstructor(),
- hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
- EqualsVerifier.forClass(BulkOperation.class)
- .suppress(Warning.NONFINAL_FIELDS).verify();
+ while (times > 0) {
+ op = new BulkOperation();
+ op.setMethod("GET");
+ op.setUrl("/home");
+ op.getHeaders().put("Authorization", authHeader);
+ req.getOperations().add(op);
- assertThat(BulkRequest.class, allOf(hasValidBeanConstructor(),
- hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
- EqualsVerifier.forClass(BulkRequest.class).suppress(Warning.NONFINAL_FIELDS)
- .verify();
+ times--;
+ }
- assertThat(BulkResponse.class, allOf(hasValidBeanConstructor(),
- hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
- EqualsVerifier.forClass(BulkResponse.class)
- .suppress(Warning.NONFINAL_FIELDS).verify();
+ return req;
+ }
- assertThat(BulkResult.class, allOf(hasValidBeanConstructor(),
- hasValidGettersAndSetters(), hasValidBeanToStringExcluding()));
- EqualsVerifier.forClass(BulkResult.class).suppress(Warning.NONFINAL_FIELDS)
- .verify();
- }
+ @Test
+ public void testBatch() throws Exception {
+ HttpEntity entity = new ByteArrayEntity(
+ mapper.writeValueAsString(operationTimes(1000)).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+ String result = EntityUtils.toString(response.getEntity());
+ BulkResponse res = new Gson().getAdapter(new TypeToken() {
+ })
+ .fromJson(result);
+
+ assertTrue(200 == Double.valueOf(res.getResults().get(0).getStatus()));
+ assertEquals(1000, res.getResults().size());
+ }
- private BulkRequest operationTimes(int times) {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
+ @Test
+ public void testOverLimitationError() throws Exception {
+ HttpEntity entity = new ByteArrayEntity(
+ mapper.writeValueAsString(operationTimes(1001)).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
- times--;
+ assertEquals(413, response.getStatusLine().getStatusCode());
+ }
- op.setMethod("GET");
- op.setUrl("home");
- op.getHeaders().put("Authorization", authHeader);
- req.getOperations().add(op);
+ @Test
+ public void testSilentMode() throws Exception {
+ BulkRequest req = operationTimes(1);
+ BulkOperation op = new BulkOperation();
+ op.setMethod("GET");
+ op.setUrl("/home");
+ op.getHeaders().put("Authorization", authHeader);
+ op.setSilent(true);
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+ String result = EntityUtils.toString(response.getEntity());
+ BulkResponse res = new Gson().getAdapter(new TypeToken() {
+ })
+ .fromJson(result);
+
+ assertEquals(1, res.getResults().size());
+ }
- while (times > 0) {
- op = new BulkOperation();
- op.setMethod("GET");
- op.setUrl("/home");
- op.getHeaders().put("Authorization", authHeader);
- req.getOperations().add(op);
+ @Test
+ public void testInvalidUrl() throws Exception {
+ BulkRequest req = operationTimes(1);
+ BulkOperation op = new BulkOperation();
+ op.setMethod("GET");
+ op.setUrl("http://0:0:0:0:0:0:0:1%0:8080/home");
+ op.getHeaders().put("Authorization", authHeader);
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(422 == response.getStatusLine().getStatusCode());
+ }
- times--;
+ @Test
+ public void bulkRequestCanNotContainBulkPathAsUrl() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl(bulkPath);
+ op.setMethod("GET");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(422 == response.getStatusLine().getStatusCode());
}
- return req;
- }
-
- @Test
- public void testBatch() throws Exception {
- HttpEntity entity = new ByteArrayEntity(
- mapper.writeValueAsString(operationTimes(1000)).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
- String result = EntityUtils.toString(response.getEntity());
- BulkResponse res = new Gson().getAdapter(new TypeToken() {})
- .fromJson(result);
-
- assertTrue(200 == Double.valueOf(res.getResults().get(0).getStatus()));
- assertEquals(1000, res.getResults().size());
- }
-
- @Test
- public void testOverLimitationError() throws Exception {
- HttpEntity entity = new ByteArrayEntity(
- mapper.writeValueAsString(operationTimes(1001)).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertEquals(413, response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testSilentMode() throws Exception {
- BulkRequest req = operationTimes(1);
- BulkOperation op = new BulkOperation();
- op.setMethod("GET");
- op.setUrl("/home");
- op.getHeaders().put("Authorization", authHeader);
- op.setSilent(true);
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
- String result = EntityUtils.toString(response.getEntity());
- BulkResponse res = new Gson().getAdapter(new TypeToken() {})
- .fromJson(result);
-
- assertEquals(1, res.getResults().size());
- }
-
- @Test
- public void testInvalidUrl() throws Exception {
- BulkRequest req = operationTimes(1);
- BulkOperation op = new BulkOperation();
- op.setMethod("GET");
- op.setUrl("http://0:0:0:0:0:0:0:1%0:8080/home");
- op.getHeaders().put("Authorization", authHeader);
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(422 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestCanNotContainBulkPathAsUrl() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl(bulkPath);
- op.setMethod("GET");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(422 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestToComplexMapping() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("/home2/AAA/ccc");
- op.setMethod("PUT");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(200 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestToWrongMapping() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("/home2/BBB/ccc");
- op.setMethod("PUT");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(422 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestToNonBulkableMapping() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("home3");
- op.setMethod("PUT");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(422 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestWithParam() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("/home4");
- op.setMethod("POST");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- op.getParams().put("abc", "abc");
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(200 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestByRequestBodyWithNestedObject() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("/list");
- op.setMethod("POST");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- Map params = new HashMap() {
- private static final long serialVersionUID = 1L;
- {
- put("a", Ruby.Hash.of("c", "D").toMap());
- put("b", "E");
- }
- };
- op.setParams(params);
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(200 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void bulkRequestByRequestBodyWithObject() throws Exception {
- BulkRequest req = new BulkRequest();
- BulkOperation op = new BulkOperation();
- op.setUrl("list2");
- op.setMethod("POST");
- op.getHeaders().put("Authorization",
- "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
- Map params = new HashMap() {
- private static final long serialVersionUID = 1L;
- {
- put("a", "D");
- put("b", "E");
- }
- };
- op.setParams(params);
- req.getOperations().add(op);
-
- HttpEntity entity =
- new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
- post.setEntity(entity);
- HttpResponse response = client.execute(post);
-
- assertTrue(200 == response.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testURITransformer() {
- assertTrue(testUriTransformer.isUsed());
- }
+ @Test
+ public void bulkRequestToComplexMapping() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("/home2/AAA/ccc");
+ op.setMethod("PUT");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(200 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void bulkRequestToWrongMapping() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("/home2/BBB/ccc");
+ op.setMethod("PUT");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(422 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void bulkRequestToNonBulkableMapping() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("home3");
+ op.setMethod("PUT");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(422 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void bulkRequestWithParam() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("/home4");
+ op.setMethod("POST");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ op.getParams().put("abc", "abc");
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(200 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void bulkGetRequestWithParam() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ String queryParamValue = "query_param";
+ op.setUrl("/getwithparameter?abc=" + queryParamValue);
+ op.setMethod("GET");
+ op.setPayload("requestNo:1");
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ String responseString = new BasicResponseHandler().handleResponse(response);
+ System.out.println(responseString);
+
+ //region Check if status first request of bulk is 200 or 400(in case of not to having query param)
+ JSONParser parser = new JSONParser();
+ JSONObject json = (JSONObject) parser.parse(responseString);
+ JSONArray slideContent = (JSONArray)json.get("results");
+ JSONObject result0 = (JSONObject) slideContent.get(0);
+ //endregion
+
+ assertTrue((Long)result0.get("status")==200);
+ }
+
+ @Test
+ public void bulkRequestByRequestBodyWithNestedObject() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("/list");
+ op.setMethod("POST");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ Map params = new HashMap() {
+ private static final long serialVersionUID = 1L;
+
+ {
+ put("a", Ruby.Hash.of("c", "D").toMap());
+ put("b", "E");
+ }
+ };
+ op.setParams(params);
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(200 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void bulkRequestByRequestBodyWithObject() throws Exception {
+ BulkRequest req = new BulkRequest();
+ BulkOperation op = new BulkOperation();
+ op.setUrl("list2");
+ op.setMethod("POST");
+ op.getHeaders().put("Authorization",
+ "Basic " + Base64Utils.encodeToString("user:password".getBytes()));
+ Map params = new HashMap() {
+ private static final long serialVersionUID = 1L;
+
+ {
+ put("a", "D");
+ put("b", "E");
+ }
+ };
+ op.setParams(params);
+ req.getOperations().add(op);
+
+ HttpEntity entity =
+ new ByteArrayEntity(mapper.writeValueAsString(req).getBytes("UTF-8"));
+ post.setEntity(entity);
+ HttpResponse response = client.execute(post);
+
+ assertTrue(200 == response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testURITransformer() {
+ assertTrue(testUriTransformer.isUsed());
+ }
}
diff --git a/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController6.java b/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController6.java
new file mode 100644
index 0000000..f8fcbd1
--- /dev/null
+++ b/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController6.java
@@ -0,0 +1,28 @@
+package com.github.wnameless.spring.bulkapi.test;
+
+import lombok.SneakyThrows;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.github.wnameless.spring.bulkapi.Bulkable;
+
+import java.io.IOException;
+
+
+/**
+ * Created by Arash Moghani on 15 Jul 2020
+ */
+
+@Bulkable
+@RestController
+public class TestController6 {
+
+ @SneakyThrows
+ @RequestMapping("/exception")
+ String exception() {
+ throw new IOException(); // Creating error intentionally
+ }
+
+}
+
+
diff --git a/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController7.java b/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController7.java
new file mode 100644
index 0000000..0232034
--- /dev/null
+++ b/src/test/java/com/github/wnameless/spring/bulkapi/test/TestController7.java
@@ -0,0 +1,26 @@
+package com.github.wnameless.spring.bulkapi.test;
+
+import com.github.wnameless.spring.bulkapi.Bulkable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * Created by Arash Moghani on 22 Jul 2020
+ */
+
+@Bulkable
+@RestController
+public class TestController7 {
+
+ @RequestMapping("/getwithparameter")
+ String getWithParameter(@RequestParam("abc") String param) {
+ System.out.println(param);
+ return param;
+
+ }
+
+}
+
+