headers) {
56 | this.headers = headers;
57 | }
58 | }
--------------------------------------------------------------------------------
/docker/README.md:
--------------------------------------------------------------------------------
1 | # Supported tags and respective `Dockerfile` links
2 | - `v1.0.0`, `latest` [(Dockerfile)](Dockerfile)
3 |
4 | # Quick reference
5 | Due to Oracle's JDK license, you must build this Docker image using the official Oracle image located in the Docker Store. You will need a Docker store account. Once you have an account, you must accept the Oracle license [here](https://store.docker.com/images/oracle-serverjre-8). On the command line, type `docker login` and provide your credentials. You may then build the image using this command `docker build -t sendgrid/java-http-client -f Dockerfile .`
6 |
7 | - **Where to get help:**
8 | [Contact SendGrid Support](https://support.sendgrid.com/hc/en-us)
9 |
10 | - **Where to file issues:**
11 | https://github.com/sendgrid/java-http-client/issues
12 |
13 | - **Where to get more info:**
14 | [USAGE.md](USAGE.md)
15 |
16 | - **Maintained by:**
17 | [SendGrid Inc.](https://sendgrid.com)
18 |
19 | # Usage examples
20 | - Most recent version: `docker run -it sendgrid/java-http-client`.
21 | - Your own fork:
22 | ```sh-session
23 | $ git clone https://github.com/you/cool-java-http-client.git
24 | $ realpath cool-java-http-client
25 | /path/to/cool-java-http-client
26 | $ docker run -it -v /path/to/cool-java-http-client:/mnt/java-http-client sendgrid/java-http-client
27 | ```
28 |
29 | For more detailed information, see [USAGE.md](USAGE.md).
30 |
31 | 
32 |
--------------------------------------------------------------------------------
/src/main/java/com/sendgrid/SendGridResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.sendgrid;
2 |
3 | import java.io.IOException;
4 |
5 | import org.apache.http.HttpEntity;
6 | import org.apache.http.HttpResponse;
7 | import org.apache.http.client.HttpResponseException;
8 | import org.apache.http.impl.client.AbstractResponseHandler;
9 | import org.apache.http.util.EntityUtils;
10 | import java.nio.charset.StandardCharsets;
11 |
12 | /**
13 | * A {@link org.apache.http.client.ResponseHandler} that returns the response body as a String
14 | * for all responses.
15 | *
16 | * If this is used with
17 | * {@link org.apache.http.client.HttpClient#execute(
18 | * org.apache.http.client.methods.HttpUriRequest, org.apache.http.client.ResponseHandler)},
19 | * HttpClient may handle redirects (3xx responses) internally.
20 | *
21 | *
22 | */
23 | public class SendGridResponseHandler extends AbstractResponseHandler{
24 |
25 | /**
26 | * Read the entity from the response body and pass it to the entity handler
27 | * method if the response was successful (a 2xx status code). If no response
28 | * body exists, this returns null. If the response was unsuccessful (>= 500
29 | * status code), throws an {@link HttpResponseException}.
30 | */
31 | @Override
32 | public String handleResponse(final HttpResponse response)
33 | throws HttpResponseException, IOException {
34 | final HttpEntity entity = response.getEntity();
35 | return entity == null ? null : handleEntity(entity);
36 | }
37 |
38 | @Override
39 | public String handleEntity(HttpEntity entity) throws IOException {
40 | return EntityUtils.toString(entity, StandardCharsets.UTF_8);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
16 |
17 | # Fixes #
18 |
19 | A short description of what this PR does.
20 |
21 | ### Checklist
22 | - [x] I acknowledge that all my contributions will be made under the project's license
23 | - [ ] I have made a material change to the repo (functionality, testing, spelling, grammar)
24 | - [ ] I have read the [Contribution Guidelines](https://github.com/sendgrid/java-http-client/blob/main/CONTRIBUTING.md) and my PR follows them
25 | - [ ] I have titled the PR appropriately
26 | - [ ] I have updated my branch with the main branch
27 | - [ ] I have added tests that prove my fix is effective or that my feature works
28 | - [ ] I have added the necessary documentation about the functionality in the appropriate .md file
29 | - [ ] I have added inline documentation to the code I modified
30 |
31 | If you have questions, please file a [support ticket](https://support.sendgrid.com), or create a GitHub Issue in this repository.
32 |
--------------------------------------------------------------------------------
/.github/workflows/update-dependencies.yml:
--------------------------------------------------------------------------------
1 | name: Update dependencies
2 | on:
3 | schedule:
4 | # Run automatically at 7AM PST Tuesday
5 | - cron: '0 14 * * 2'
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update-dependencies-and-test:
10 | name: Update Dependencies & Test
11 | runs-on: ubuntu-latest
12 | timeout-minutes: 20
13 | strategy:
14 | max-parallel: 1
15 | matrix:
16 | java: [ 8, 11, 17 ]
17 |
18 | steps:
19 | - name: Checkout java-http-client
20 | uses: actions/checkout@v2
21 |
22 | - name: Set up Java
23 | uses: actions/setup-java@v2
24 | with:
25 | distribution: 'temurin'
26 | java-version: ${{ matrix.java }}
27 | cache: 'maven'
28 |
29 | - name: Updating semver dependencies
30 | run: make update-deps
31 |
32 | - run: mvn install -Dgpg.skip -Dmaven.javadoc.skip=true -B -V
33 |
34 | - name: Add & Commit
35 | if: matrix.java == '17'
36 | uses: EndBug/add-and-commit@v8.0.2
37 | env:
38 | GITHUB_TOKEN: ${{ secrets.SG_JAVA_GITHUB_TOKEN }}
39 | with:
40 | add: 'pom.xml'
41 | default_author: 'github_actions'
42 | message: 'chore: update java-http-client dependencies'
43 |
44 | notify-on-failure:
45 | name: Slack notify on failure
46 | if: failure()
47 | needs: [ update-dependencies-and-test ]
48 | runs-on: ubuntu-latest
49 | steps:
50 | - uses: rtCamp/action-slack-notify@v2
51 | env:
52 | SLACK_COLOR: failure
53 | SLACK_ICON_EMOJI: ':github:'
54 | SLACK_MESSAGE: ${{ format('Update dependencies *{0}*, {1}/{2}/actions/runs/{3}', needs.update-dependencies-and-test.result, github.server_url, github.repository, github.run_id) }}
55 | SLACK_TITLE: Action Failure - ${{ github.repository }}
56 | SLACK_USERNAME: GitHub Actions
57 | SLACK_MSG_AUTHOR: twilio-dx
58 | SLACK_FOOTER: Posted automatically using GitHub Actions
59 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
60 | MSG_MINIMAL: true
61 |
--------------------------------------------------------------------------------
/src/test/java/com/sendgrid/TestRequiredFilesExist.java:
--------------------------------------------------------------------------------
1 | import org.junit.Test;
2 |
3 | import java.io.File;
4 |
5 | import static org.junit.Assert.assertTrue;
6 |
7 | public class TestRequiredFilesExist {
8 |
9 | // ./Docker or docker/Docker
10 | @Test public void checkDockerExists() {
11 | boolean dockerExists = new File("./docker/Dockerfile").exists() ||
12 | new File("./docker/Docker").exists();
13 | assertTrue(dockerExists);
14 | }
15 |
16 | /* // ./docker-compose.yml or ./docker/docker-compose.yml
17 | @Test public void checkDockerComposeExists() {
18 | boolean dockerComposeExists = new File("./docker-compose.yml").exists() ||
19 | new File("./docker/docker-compose.yml").exists();
20 | assertTrue(dockerComposeExists);
21 | }
22 | // ./.env_sample
23 | @Test public void checkEnvSampleExists() {
24 | assertTrue(new File("./.env_sample").exists());
25 | } */
26 |
27 | // ./.gitignore
28 | @Test public void checkGitIgnoreExists() {
29 | assertTrue(new File("./.gitignore").exists());
30 | }
31 |
32 |
33 | // ./CHANGELOG.md
34 | @Test public void checkChangelogExists() {
35 | assertTrue(new File("./CHANGELOG.md").exists());
36 | }
37 |
38 | // ./CODE_OF_CONDUCT.md
39 | @Test public void checkCodeOfConductExists() {
40 | assertTrue(new File("./CODE_OF_CONDUCT.md").exists());
41 | }
42 |
43 | // ./CONTRIBUTING.md
44 | @Test public void checkContributingGuideExists() {
45 | assertTrue(new File("./CONTRIBUTING.md").exists());
46 | }
47 |
48 | // ./LICENSE
49 | @Test public void checkLicenseExists() {
50 | assertTrue(new File("./LICENSE").exists());
51 | }
52 |
53 | // ./PULL_REQUEST_TEMPLATE.md
54 | @Test public void checkPullRequestExists() {
55 | assertTrue(new File("./PULL_REQUEST_TEMPLATE.md").exists());
56 | }
57 |
58 | // ./README.md
59 | @Test public void checkReadMeExists() {
60 | assertTrue(new File("./README.md").exists());
61 | }
62 |
63 | // ./TROUBLESHOOTING.md
64 | @Test public void checkTroubleShootingGuideExists() {
65 | assertTrue(new File("./TROUBLESHOOTING.md").exists());
66 | }
67 |
68 | // ./USAGE.md
69 | @Test public void checkUsageGuideExists() {
70 | assertTrue(new File("./USAGE.md").exists());
71 | }
72 |
73 | /* // ./USE_CASES.md
74 | @Test public void checkUseCases() {
75 | assertTrue(new File("./USE_CASES.md").exists());
76 | } */
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/sendgrid/Request.java:
--------------------------------------------------------------------------------
1 | package com.sendgrid;
2 |
3 | import java.util.Map;
4 | import java.util.HashMap;
5 |
6 | /**
7 | * Class Response provides a standard interface to an API's HTTP request.
8 | */
9 | public class Request {
10 | private Method method;
11 | private String baseUri;
12 | private String endpoint;
13 | private String body;
14 | private final Map headers;
15 | private final Map queryParams;
16 |
17 | public Request() {
18 | this.headers = new HashMap();
19 | this.queryParams = new HashMap();
20 | this.reset();
21 | }
22 |
23 | /**
24 | * Place the object into an empty state.
25 | */
26 | public void reset() {
27 | this.clearMethod();
28 | this.clearBaseUri();
29 | this.clearEndpoint();
30 | this.clearBody();
31 | this.clearHeaders();
32 | this.clearQueryParams();
33 | }
34 |
35 | public void addQueryParam(String key, String value) {
36 | this.queryParams.put(key, value);
37 | }
38 |
39 | public void addHeader(String key, String value) {
40 | this.headers.put(key, value);
41 | }
42 |
43 | public String removeQueryParam(String key) {
44 | return this.queryParams.remove(key);
45 | }
46 |
47 | public String removeHeader(String key) {
48 | return this.headers.remove(key);
49 | }
50 |
51 | public void setMethod(Method method) {
52 | this.method = method;
53 | }
54 |
55 | public void setBaseUri(String baseUri) {
56 | this.baseUri = baseUri;
57 | }
58 |
59 | public void setEndpoint(String endpoint) {
60 | this.endpoint = endpoint;
61 | }
62 |
63 | public void setBody(String body) {
64 | this.body = body;
65 | }
66 |
67 | public Map getHeaders() {
68 | return this.headers;
69 | }
70 |
71 | public Map getQueryParams() {
72 | return this.queryParams;
73 | }
74 |
75 | public Method getMethod() {
76 | return this.method;
77 | }
78 |
79 | public String getBaseUri() {
80 | return this.baseUri;
81 | }
82 |
83 | public String getEndpoint() {
84 | return this.endpoint;
85 | }
86 |
87 | public String getBody() {
88 | return this.body;
89 | }
90 |
91 | public void clearMethod() {
92 | this.method = null;
93 | }
94 |
95 | public void clearBaseUri() {
96 | this.baseUri = "";
97 | }
98 |
99 | public void clearEndpoint() {
100 | this.endpoint = "";
101 | }
102 |
103 | public void clearBody() {
104 | this.body = "";
105 | }
106 |
107 | public void clearQueryParams() {
108 | this.queryParams.clear();
109 | }
110 |
111 | public void clearHeaders() {
112 | this.headers.clear();
113 | }
114 | }
--------------------------------------------------------------------------------
/FIRST_TIMERS.md:
--------------------------------------------------------------------------------
1 | # How To Contribute to Twilio SendGrid Repositories via GitHub
2 | Contributing to the Twilio SendGrid repositories is easy! All you need to do is find an open issue (see the bottom of this page for a list of repositories containing open issues), fix it and submit a pull request. Once you have submitted your pull request, the team can easily review it before it is merged into the repository.
3 |
4 | To make a pull request, follow these steps:
5 |
6 | 1. Log into GitHub. If you do not already have a GitHub account, you will have to create one in order to submit a change. Click the Sign up link in the upper right-hand corner to create an account. Enter your username, password, and email address. If you are an employee of Twilio SendGrid, please use your full name with your GitHub account and enter Twilio SendGrid as your company so we can easily identify you.
7 |
8 |
9 |
10 | 2. __[Fork](https://help.github.com/fork-a-repo/)__ the [java-http-client](https://github.com/sendgrid/java-http-client) repository:
11 |
12 |
13 |
14 | 3. __Clone__ your fork via the following commands:
15 |
16 | ```bash
17 | # Clone your fork of the repo into the current directory
18 | git clone https://github.com/your_username/java-http-client
19 | # Navigate to the newly cloned directory
20 | cd java-http-client
21 | # Assign the original repo to a remote called "upstream"
22 | git remote add upstream https://github.com/sendgrid/java-http-client
23 | ```
24 |
25 | > Don't forget to replace *your_username* in the URL by your real GitHub username.
26 |
27 | 4. __Create a new topic branch__ (off the main project development branch) to contain your feature, change, or fix:
28 |
29 | ```bash
30 | git checkout -b
31 | ```
32 |
33 | 5. __Commit your changes__ in logical chunks.
34 |
35 | Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) or your code is unlikely be merged into the main project. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. Probably you will also have to create tests (if needed) or create or update the example code that demonstrates the functionality of this change to the code.
36 |
37 | 6. __Locally merge (or rebase)__ the upstream development branch into your topic branch:
38 |
39 | ```bash
40 | git pull [--rebase] upstream main
41 | ```
42 |
43 | 7. __Push__ your topic branch up to your fork:
44 |
45 | ```bash
46 | git push origin
47 | ```
48 |
49 | 8. __[Open a Pull Request](https://help.github.com/articles/creating-a-pull-request/#changing-the-branch-range-and-destination-repository/)__ with a clear title and description against the `main` branch. All tests must be passing before we will review the PR.
50 |
51 | ## Important notice
52 |
53 | Before creating a pull request, make sure that you respect the repository's constraints regarding contributions. You can find them in the [CONTRIBUTING.md](CONTRIBUTING.md) file.
54 |
--------------------------------------------------------------------------------
/.github/workflows/test-and-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Test and Deploy
2 | on:
3 | push:
4 | branches: [ '*' ]
5 | tags: [ '*' ]
6 | pull_request:
7 | branches: [ main ]
8 | schedule:
9 | # Run automatically at 8AM PST Monday-Friday
10 | - cron: '0 15 * * 1-5'
11 | workflow_dispatch:
12 |
13 | jobs:
14 | test:
15 | name: Test
16 | runs-on: ubuntu-latest
17 | timeout-minutes: 20
18 | strategy:
19 | matrix:
20 | java: [ 8, 11, 17 ]
21 | steps:
22 | - uses: actions/checkout@v2
23 |
24 | - name: Set up Java
25 | uses: actions/setup-java@v2
26 | with:
27 | distribution: 'temurin'
28 | java-version: ${{ matrix.java }}
29 | cache: 'maven'
30 |
31 | - run: mvn install -DskipTests=true -Dgpg.skip -Dmaven.javadoc.skip=true -B -V
32 | - name: Run Unit Tests
33 | run: mvn test -B
34 |
35 | deploy:
36 | name: Deploy
37 | if: success() && github.ref_type == 'tag'
38 | needs: [ test ]
39 | runs-on: ubuntu-latest
40 | steps:
41 | - uses: actions/checkout@v2
42 |
43 | - name: Set up Sonatype Maven
44 | uses: actions/setup-java@v2
45 | with:
46 | java-version: 8
47 | distribution: temurin
48 | server-id: ossrh
49 | server-username: MAVEN_USERNAME
50 | server-password: MAVEN_PASSWORD
51 | gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
52 | gpg-passphrase: GPG_PASSPHRASE
53 |
54 | - name: Install Dependencies
55 | run: make install
56 |
57 | - name: Create GitHub Release
58 | uses: sendgrid/dx-automator/actions/release@main
59 | with:
60 | assets: java-http-client.jar
61 | footer: '**[Maven](https://mvnrepository.com/artifact/com.sendgrid/java-http-client/${version})**'
62 | env:
63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64 |
65 | - name: Publish to Maven
66 | env:
67 | MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
68 | MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
69 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
70 | run: mvn clean deploy -DskipTests=true -B -U -Prelease
71 |
72 | - name: Submit metric to Datadog
73 | uses: sendgrid/dx-automator/actions/datadog-release-metric@main
74 | env:
75 | DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
76 |
77 | notify-on-failure:
78 | name: Slack notify on failure
79 | if: failure() && github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref_type == 'tag')
80 | needs: [ test, deploy ]
81 | runs-on: ubuntu-latest
82 | steps:
83 | - uses: rtCamp/action-slack-notify@v2
84 | env:
85 | SLACK_COLOR: failure
86 | SLACK_ICON_EMOJI: ':github:'
87 | SLACK_MESSAGE: ${{ format('Test *{0}*, Deploy *{1}*, {2}/{3}/actions/runs/{4}', needs.test.result, needs.deploy.result, github.server_url, github.repository, github.run_id) }}
88 | SLACK_TITLE: Action Failure - ${{ github.repository }}
89 | SLACK_USERNAME: GitHub Actions
90 | SLACK_MSG_AUTHOR: twilio-dx
91 | SLACK_FOOTER: Posted automatically using GitHub Actions
92 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
93 | MSG_MINIMAL: true
94 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at open-source@twilio.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
--------------------------------------------------------------------------------
/examples/Example.java:
--------------------------------------------------------------------------------
1 | import com.fasterxml.jackson.databind.JsonNode;
2 | import com.fasterxml.jackson.databind.ObjectMapper;
3 |
4 | import com.sendgrid.Client;
5 | import com.sendgrid.Method;
6 | import com.sendgrid.Request;
7 | import com.sendgrid.Response;
8 |
9 | import java.io.IOException;
10 | import java.io.OutputStream;
11 | import java.net.URISyntaxException;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 |
15 | public class Example {
16 |
17 | private static String apiKeyId = "";
18 |
19 | private static void getCollection(Client client, Request request) throws IOException {
20 | request.setMethod(Method.GET);
21 | request.setEndpoint("/v3/api_keys");
22 | request.addQueryParam("limit", "100");
23 | request.addQueryParam("offset", "0");
24 | try {
25 | processResponse();
26 | } catch (IOException ex) {
27 | throw ex;
28 | }
29 | request.clearQueryParams();
30 | }
31 |
32 | private static void post(Client client, Request request) throws IOException {
33 | request.setMethod(Method.POST);
34 | request.setEndpoint("/v3/api_keys");
35 | request.setBody("{\"name\": \"My api Key\",\"scopes\": [\"mail.send\",\"alerts.create\",\"alerts.read\"]}");
36 |
37 | try {
38 | processResponse();
39 | } catch (IOException ex) {
40 | throw ex;
41 | }
42 | String apiKeyId = "";
43 | try {
44 | ObjectMapper mapper = new ObjectMapper();
45 | JsonNode json = mapper.readTree(response.getBody());
46 | apiKeyId = json.path("api_key_id").asText();
47 | } catch (IOException ex) {
48 | throw ex;
49 | }
50 | request.clearBody();
51 | }
52 |
53 | private static void getSingle(Client client, Request request) throws IOException {
54 | request.setMethod(Method.GET);
55 | request.setEndpoint("/v3/api_keys/" + apiKeyId);
56 | try {
57 | processResponse();
58 | } catch (IOException ex) {
59 | throw ex;
60 | }
61 | }
62 |
63 | private static void patch(Client client, Request request) throws IOException {
64 | request.setMethod(Method.PATCH);
65 | request.setBody("{\"name\": \"A New Ho}");
66 | try {
67 | processResponse();
68 | } catch (IOException ex) {
69 | throw ex;
70 | }
71 | request.clearBody();
72 | }
73 |
74 | private static void put(Client client, Request request) throws IOException {
75 | request.setMethod(Method.PUT);
76 | request.setBody("{\"name\": \"A New Hope\",\"scopes\": [\"user.profile.read\",\"user.profile.update\"]}");
77 | try {
78 | processResponse();
79 | } catch (IOException ex) {
80 | throw ex;
81 | }
82 | request.clearBody();
83 | }
84 |
85 | private static void delete(Client client, Request request) throws IOException {
86 | request.setMethod(Method.DELETE);
87 | try {
88 | Response response = client.api(request);
89 | System.out.println(response.getStatusCode());
90 | System.out.println(response.getHeaders());
91 | } catch (IOException ex) {
92 | throw ex;
93 | }
94 | }
95 |
96 | public static void main(String[] args) throws IOException {
97 | Client client = new Client();
98 |
99 | Request request = new Request();
100 | request.setBaseUri("api.sendgrid.com");
101 | request.addHeader("Authorization", "Bearer " + System.getenv("SENDGRID_API_KEY"));
102 |
103 | // GET Collection
104 | getCollection(client, request);
105 |
106 | // POST
107 | post(client, request);
108 |
109 | // GET Single
110 | getSingle(client, request);
111 |
112 | // PATCH
113 | patch(client, request);
114 |
115 | // PUT
116 | put(client, request);
117 |
118 | // DELETE
119 | delete(client, request);
120 | }
121 |
122 | //Refactor method
123 | private void processResponse(){
124 | response = client.api(request);
125 | System.out.println(response.getStatusCode());
126 | System.out.println(response.getBody());
127 | System.out.println(response.getHeaders());
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://github.com/sendgrid/java-http-client/actions/workflows/test-and-deploy.yml)
4 | [](http://mvnrepository.com/artifact/com.sendgrid/java-http-client)
5 | [](LICENSE)
6 | [](https://twitter.com/sendgrid)
7 | [](https://github.com/sendgrid/java-http-client/graphs/contributors)
8 |
9 | **Quickly and easily access any RESTful or RESTful-like API.**
10 |
11 | If you are looking for the SendGrid API client library, please see [this repo](https://github.com/sendgrid/sendgrid-java).
12 |
13 | # Table of Contents
14 |
15 | * [Announcements](#announcements)
16 | * [Installation](#installation)
17 | * [Quick Start](#quick-start)
18 | * [Usage](./USAGE.md)
19 | * [How to Contribute](#contribute)
20 | * [About](#about)
21 | * [Support](#support)
22 | * [License](#license)
23 |
24 |
25 | # Announcements
26 |
27 | All updates to this project are documented in our [CHANGELOG](CHANGELOG.md).
28 |
29 |
30 | # Installation
31 |
32 | ## Prerequisites
33 |
34 | - Java 8, 11, or 17
35 |
36 | ## Install via Maven w/ Gradle
37 |
38 | ```groovy
39 | ...
40 | dependencies {
41 | ...
42 | compile 'com.sendgrid:java-http-client:4.5.1'
43 | }
44 |
45 | repositories {
46 | mavenCentral()
47 | }
48 | ...
49 | ```
50 |
51 | ### Maven
52 |
53 | ```xml
54 |
55 | com.sendgrid
56 | java-http-client
57 | 4.5.1
58 |
59 | ```
60 |
61 | `mvn install`
62 |
63 | ## Dependencies
64 |
65 | - Please see the [pom.xml file](pom.xml)
66 |
67 |
68 | # Quick Start
69 |
70 | Here is a quick example:
71 |
72 | `GET /your/api/{param}/call`
73 |
74 | ```java
75 | Client client = new Client();
76 |
77 | Request request = new Request();
78 | request.setBaseUri("api.test.com");
79 | request.setMethod(Method.GET);
80 | String param = "param";
81 | request.setEndpoint("/your/api/" + param + "/call");
82 |
83 | try {
84 | Response response = client.api(request);
85 | System.out.println(response.getStatusCode());
86 | System.out.println(response.getBody());
87 | System.out.println(response.getHeaders());
88 | } catch (IOException ex) {
89 | throw ex;
90 | }
91 | ```
92 |
93 | `POST /your/api/{param}/call` with headers, query parameters and a request body.
94 |
95 | ```java
96 | request.addHeader("Authorization", "Bearer YOUR_API_KEY");
97 | request.addQueryParam("limit", "100");
98 | request.addQueryParam("offset", "0");
99 | // Will be parsed to categories=cake&categories=pie&categories=baking
100 | request.addQueryParam("categories", "cake&pie&baking");
101 | request.setBody("{\"name\": \"My Request Body\"}");
102 | request.setMethod(Method.POST);
103 | String param = "param";
104 | request.setEndpoint("/your/api/" + param + "/call");
105 |
106 | try {
107 | Response response = client.api(request);
108 | System.out.println(response.getStatusCode());
109 | System.out.println(response.getBody());
110 | System.out.println(response.getHeaders());
111 | } catch (IOException ex) {
112 | throw ex;
113 | }
114 | ```
115 |
116 |
117 | # How to Contribute
118 |
119 | We encourage contribution to our projects please see our [CONTRIBUTING](CONTRIBUTING.md) guide for details.
120 |
121 | Quick links:
122 |
123 | - [Feature Request](CONTRIBUTING.md#feature-request)
124 | - [Bug Reports](CONTRIBUTING.md#submit-a-bug-report)
125 | - [Improvements to the Codebase](CONTRIBUTING.md#improvements-to-the-codebase)
126 | - [Review Pull Requests](CONTRIBUTING.md#Code-Reviews)
127 |
128 |
129 | # About
130 |
131 | java-http-client is maintained and funded by Twilio SendGrid, Inc. The names and logos for java-http-client are trademarks of Twilio SendGrid, Inc.
132 |
133 |
134 | # Support
135 |
136 | If you need help using SendGrid, please check the [Twilio SendGrid Support Help Center](https://support.sendgrid.com).
137 |
138 | If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo!
139 |
140 | # License
141 | [The MIT License (MIT)](LICENSE)
142 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Hello! Thank you for choosing to help contribute to one of the SendGrid open source projects. There are many ways you can contribute and help is always welcome. We simply ask that you follow the following contribution policies.
2 |
3 | - [Improvements to the Codebase](#improvements-to-the-codebase)
4 | - [Understanding the Code Base](#understanding-the-codebase)
5 | - [Testing](#testing)
6 | - [Style Guidelines & Naming Conventions](#style-guidelines-and-naming-conventions)
7 | - [Creating a Pull Request](#creating-a-pull-request)
8 | - [Code Reviews](#code-reviews)
9 |
10 |
11 | ## Improvements to the Codebase
12 |
13 | We welcome direct contributions to the java-http-client code base. Thank you!
14 |
15 | ### Development Environment ###
16 |
17 | #### Install and Run Locally ####
18 |
19 | ##### Prerequisites #####
20 |
21 | - Java 8 or 11
22 | - Please see [pom.xml](pom.xml)
23 |
24 | ##### Initial setup: #####
25 |
26 | ```bash
27 | git clone https://github.com/sendgrid/java-http-client.git
28 | cd java-http-client
29 | ```
30 |
31 | ##### Execute: #####
32 |
33 | See the [examples folder](examples) to get started quickly.
34 |
35 | You will need to setup the following environment to use the SendGrid example:
36 |
37 | ```bash
38 | echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
39 | echo "sendgrid.env" >> .gitignore
40 | source ./sendgrid.env
41 | ```
42 |
43 | ```bash
44 | ./gradlew build
45 | cd examples
46 | javac -classpath {path_to}/sendgrid-java-http-client-4.2.0-jar.jar:. Example.java && java -classpath {path_to}/sendgrid-java-http-client-4.2.0-jar.jar:. Example
47 | ```
48 |
49 |
50 | ## Understanding the Code Base
51 |
52 | **/examples**
53 |
54 | Working examples that demonstrate usage.
55 |
56 | **Client.java**
57 |
58 | The main function that does the heavy lifting (and external entry point) is `api`.
59 |
60 | **Method.java**
61 |
62 | These are the supported Methods.
63 |
64 | **Request.java**
65 |
66 | Provides a standard interface to an API's HTTP request.
67 |
68 | **Response.java**
69 |
70 | Provides a standard interface to an API's response.
71 |
72 |
73 | ## Testing
74 |
75 | All PRs require passing tests before the PR will be reviewed.
76 |
77 | All test files are in [`java-http-client/src/test/java/com/sendgrid`](src/test/java/com/sendgrid).
78 |
79 | For the purposes of contributing to this repo, please update the [`ClientTest.java`](src/test/java/com/sendgrid/ClientTest.java) file with unit tests as you modify the code.
80 |
81 |
82 | Run the tests:
83 |
84 | ```java
85 | ./gradlew test -i
86 | ```
87 |
88 |
89 | ## Style Guidelines & Naming Conventions
90 |
91 | Generally, we follow the style guidelines as suggested by the official language. However, we ask that you conform to the styles that already exist in the library. If you wish to deviate, please explain your reasoning.
92 |
93 | Please run your code through:
94 |
95 | - [FindBugs](http://findbugs.sourceforge.net/)
96 | - [CheckStyle](http://checkstyle.sourceforge.net/) with [Google's Java Style Guide](http://checkstyle.sourceforge.net/reports/google-java-style.html).
97 |
98 |
99 | ## Creating a Pull Request
100 |
101 | 1. [Fork](https://help.github.com/fork-a-repo/) the project, clone your fork,
102 | and configure the remotes:
103 |
104 | ```bash
105 | # Clone your fork of the repo into the current directory
106 | git clone https://github.com/sendgrid/java-http-client
107 | # Navigate to the newly cloned directory
108 | cd java-http-client
109 | # Assign the original repo to a remote called "upstream"
110 | git remote add upstream https://github.com/sendgrid/java-http-client
111 | ```
112 |
113 | 2. If you cloned a while ago, get the latest changes from upstream:
114 |
115 | ```bash
116 | git checkout
117 | git pull upstream
118 | ```
119 |
120 | 3. Create a new topic branch (off the main project development branch) to
121 | contain your feature, change, or fix:
122 |
123 | ```bash
124 | git checkout -b
125 | ```
126 |
127 | 4. Commit your changes in logical chunks. Please adhere to these [git commit
128 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
129 | or your code is unlikely to be merged into the main project. Use Git's
130 | [interactive rebase](https://help.github.com/articles/interactive-rebase)
131 | feature to tidy up your commits before making them public.
132 |
133 | 4a. Create tests.
134 |
135 | 4b. Create or update the example code that demonstrates the functionality of this change to the code.
136 |
137 | 5. Locally merge (or rebase) the upstream development branch into your topic branch:
138 |
139 | ```bash
140 | git pull [--rebase] upstream main
141 | ```
142 |
143 | 6. Push your topic branch up to your fork:
144 |
145 | ```bash
146 | git push origin
147 | ```
148 |
149 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
150 | with a clear title and description against the `main` branch. All tests must be passing before we will review the PR.
151 |
152 | ## Code Reviews
153 | If you can, please look at open PRs and review them. Give feedback and help us merge these PRs much faster! If you don't know how, GitHub has some great [information on how to review a Pull Request](https://help.github.com/articles/about-pull-request-reviews/).
154 |
--------------------------------------------------------------------------------
/src/test/java/com/sendgrid/ClientTest.java:
--------------------------------------------------------------------------------
1 | package com.sendgrid;
2 |
3 | import org.apache.http.Header;
4 | import org.apache.http.HttpEntity;
5 | import org.apache.http.HttpStatus;
6 | import org.apache.http.HttpVersion;
7 | import org.apache.http.StatusLine;
8 | import org.apache.http.client.ResponseHandler;
9 | import org.apache.http.client.methods.CloseableHttpResponse;
10 | import org.apache.http.client.methods.HttpDelete;
11 | import org.apache.http.client.methods.HttpGet;
12 | import org.apache.http.client.methods.HttpPatch;
13 | import org.apache.http.client.methods.HttpPost;
14 | import org.apache.http.client.methods.HttpPut;
15 | import org.apache.http.client.methods.HttpUriRequest;
16 | import org.apache.http.client.utils.URIBuilder;
17 | import org.apache.http.entity.InputStreamEntity;
18 | import org.apache.http.entity.StringEntity;
19 | import org.apache.http.impl.client.BasicResponseHandler;
20 | import org.apache.http.impl.client.CloseableHttpClient;
21 | import org.apache.http.impl.client.HttpClients;
22 | import org.apache.http.message.BasicHeader;
23 | import org.apache.http.message.BasicStatusLine;
24 |
25 | import org.junit.Assert;
26 | import org.junit.Before;
27 | import org.junit.Test;
28 |
29 | import org.mockito.Matchers;
30 | import org.mockito.Mockito;
31 |
32 | import java.io.ByteArrayInputStream;
33 | import java.io.IOException;
34 | import java.io.PrintWriter;
35 | import java.io.StringWriter;
36 | import java.net.MalformedURLException;
37 | import java.net.URI;
38 | import java.net.URISyntaxException;
39 | import java.net.URL;
40 | import java.util.HashMap;
41 | import java.util.Map;
42 |
43 | public class ClientTest extends Mockito {
44 |
45 | private CloseableHttpClient httpClient;
46 | private CloseableHttpResponse response;
47 | private HttpEntity entity;
48 | private StatusLine statusline;
49 |
50 | @Before
51 | public void setUp() throws Exception {
52 | this.httpClient = mock(CloseableHttpClient.class);
53 | this.response = mock(CloseableHttpResponse.class);
54 | this.entity = mock(HttpEntity.class);
55 | this.statusline = mock(StatusLine.class);
56 | }
57 |
58 | @Test
59 | public void testbuildUri() {
60 | Client client = new Client();
61 | String baseUri = "api.test.com";
62 | String endpoint = "/endpoint";
63 | URI uri = null;
64 | Map queryParams = new HashMap();
65 | queryParams.put("test1", "1");
66 | queryParams.put("test2", "2");
67 | queryParams.put("test3", "3&4&5");
68 | try {
69 | uri = client.buildUri(baseUri, endpoint, queryParams);
70 | } catch (URISyntaxException ex) {
71 | StringWriter errors = new StringWriter();
72 | ex.printStackTrace(new PrintWriter(errors));
73 | Assert.assertTrue(errors.toString(), false);
74 | }
75 |
76 | URL url = null;
77 | try {
78 | url = uri.toURL();
79 | } catch (MalformedURLException ex) {
80 | StringWriter errors = new StringWriter();
81 | ex.printStackTrace(new PrintWriter(errors));
82 | Assert.assertTrue(errors.toString(), false);
83 | }
84 |
85 | Assert.assertTrue(url.getProtocol().equals("https"));
86 | Assert.assertTrue(url.getHost().equals("api.test.com"));
87 | Assert.assertTrue(url.getPath().equals("/endpoint"));
88 | Assert.assertTrue(this.queryParamHasCorrectValue(url, "test1", "1"));
89 | Assert.assertTrue(this.queryParamHasCorrectValue(url, "test2", "2"));
90 | Assert.assertTrue(this.queryParamHasCorrectValue(url, "test3", "3"));
91 | Assert.assertTrue(this.queryParamHasCorrectValue(url, "test3", "4"));
92 | Assert.assertTrue(this.queryParamHasCorrectValue(url, "test3", "5"));
93 | }
94 |
95 | @Test
96 | public void testGetResponse() {
97 | Client client = new Client();
98 | Response testResponse = new Response();
99 | Header[] mockedHeaders = null;
100 | try {
101 | when(statusline.getStatusCode()).thenReturn(200);
102 | when(response.getStatusLine()).thenReturn(statusline);
103 | when(response.getEntity()).thenReturn(
104 | new InputStreamEntity(
105 | new ByteArrayInputStream(
106 | "{\"message\":\"success\"}".getBytes())));
107 | mockedHeaders = new Header[] { new BasicHeader("headerA", "valueA") };
108 | when(response.getAllHeaders()).thenReturn(mockedHeaders);
109 | when(httpClient.execute(Matchers.any(HttpGet.class))).thenReturn(response);
110 | HttpGet httpGet = new HttpGet("https://api.test.com");
111 | CloseableHttpResponse resp = httpClient.execute(httpGet);
112 | testResponse = client.getResponse(resp);
113 | resp.close();
114 | } catch (IOException ex) {
115 | StringWriter errors = new StringWriter();
116 | ex.printStackTrace(new PrintWriter(errors));
117 | Assert.assertTrue(errors.toString(), false);
118 | }
119 |
120 | Assert.assertTrue(testResponse.getStatusCode() == 200);
121 | Assert.assertEquals(testResponse.getBody(), "{\"message\":\"success\"}");
122 | Map headers = new HashMap();
123 | for (Header h:mockedHeaders) {
124 | headers.put(h.getName(), h.getValue());
125 | }
126 | Assert.assertEquals(testResponse.getHeaders(), headers);
127 | }
128 |
129 | public void testMethod(Method method, int statusCode) {
130 | Response testResponse = new Response();
131 | Request request = new Request();
132 | Header[] mockedHeaders = null;
133 | try {
134 | when(statusline.getStatusCode()).thenReturn(statusCode);
135 | when(response.getStatusLine()).thenReturn(statusline);
136 | when(response.getEntity()).thenReturn(
137 | new InputStreamEntity(
138 | new ByteArrayInputStream(
139 | "{\"message\":\"success\"}".getBytes())));
140 | mockedHeaders = new Header[] { new BasicHeader("headerA", "valueA") };
141 | when(response.getAllHeaders()).thenReturn(mockedHeaders);
142 | when(httpClient.execute(Matchers.any(HttpGet.class))).thenReturn(response);
143 | request.setMethod(method);
144 | if ((method == Method.POST) || (method == Method.PATCH) || (method == Method.PUT)) {
145 | request.setBody("{\"test\":\"testResult\"}");
146 | }
147 | request.setEndpoint("/test");
148 | request.addHeader("Authorization", "Bearer XXXX");
149 | Client client = new Client(httpClient);
150 | testResponse = client.get(request);
151 | } catch (URISyntaxException | IOException ex) {
152 | StringWriter errors = new StringWriter();
153 | ex.printStackTrace(new PrintWriter(errors));
154 | Assert.assertTrue(errors.toString(), false);
155 | }
156 |
157 | Assert.assertTrue(testResponse.getStatusCode() == statusCode);
158 | if (method != Method.DELETE) {
159 | Assert.assertEquals(testResponse.getBody(), "{\"message\":\"success\"}");
160 | }
161 | Assert.assertEquals(testResponse.getBody(), "{\"message\":\"success\"}");
162 | Map headers = new HashMap();
163 | for (Header h:mockedHeaders) {
164 | headers.put(h.getName(), h.getValue());
165 | }
166 | Assert.assertEquals(testResponse.getHeaders(), headers);
167 | }
168 |
169 | @Test
170 | public void testGet() {
171 | testMethod(Method.GET, 200);
172 | }
173 |
174 | @Test
175 | public void testPost() {
176 | testMethod(Method.POST, 201);
177 | }
178 |
179 | @Test
180 | public void testPatch() {
181 | testMethod(Method.PATCH, 200);
182 | }
183 |
184 | @Test
185 | public void testPut() {
186 | testMethod(Method.PUT, 200);
187 | }
188 |
189 | @Test
190 | public void testDelete() {
191 | testMethod(Method.DELETE, 204);
192 | }
193 |
194 | private boolean queryParamHasCorrectValue(URL url, String key, String value) {
195 | return url.getQuery().indexOf(key + "=" + value) != -1;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.sonatype.oss
6 | oss-parent
7 | 7
8 |
9 | com.sendgrid
10 | java-http-client
11 | jar
12 | A simple HTTP client
13 | HTTP REST client, simplified for Java
14 | 4.5.1
15 | https://github.com/sendgrid/java-http-client
16 |
17 |
18 | The MIT License (MIT)
19 | https://github.com/sendgrid/java-http-client/blob/HEAD/LICENSE
20 | repo
21 |
22 |
23 |
24 | https://github.com/sendgrid/java-http-client
25 | scm:git:git@github.com:sendgrid/java-http-client.git
26 | scm:git:git@github.com:sendgrid/java-http-client.git
27 | 4.5.1
28 |
29 |
30 |
31 | release
32 |
33 |
34 | release
35 |
36 |
37 |
38 |
39 |
40 | org.sonatype.plugins
41 | nexus-staging-maven-plugin
42 | 1.6.8
43 | true
44 |
45 | ossrh
46 | https://oss.sonatype.org/
47 | true
48 |
49 |
50 |
51 | org.apache.maven.plugins
52 | maven-source-plugin
53 | 3.0.1
54 |
55 |
56 | attach-sources
57 |
58 | jar-no-fork
59 |
60 |
61 |
62 |
63 |
64 | org.apache.maven.plugins
65 | maven-javadoc-plugin
66 | 2.10.4
67 |
68 |
69 | attach-javadocs
70 |
71 | jar
72 |
73 |
74 |
75 |
76 |
77 | org.apache.maven.plugins
78 | maven-gpg-plugin
79 | 1.6
80 |
81 |
82 | sign-artifacts
83 | verify
84 |
85 | sign
86 |
87 |
88 | ${gpg.keyname}
89 | ${gpg.passphrase}
90 |
91 | --pinentry-mode
92 | loopback
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | 1.8
104 | 1.8
105 |
106 |
107 |
108 | junit
109 | junit-dep
110 | 4.11
111 | test
112 |
113 |
114 | org.mockito
115 | mockito-core
116 | 1.10.19
117 | test
118 |
119 |
120 | org.apache.httpcomponents
121 | httpcore
122 | 4.4.15
123 |
124 |
125 | org.apache.httpcomponents
126 | httpclient
127 | 4.5.13
128 |
129 |
130 |
131 |
132 |
133 | org.jacoco
134 | jacoco-maven-plugin
135 | 0.8.5
136 |
137 |
138 |
139 | prepare-agent
140 |
141 |
142 |
143 | report
144 | test
145 |
146 | report
147 |
148 |
149 |
150 |
151 |
152 | org.apache.maven.plugins
153 | maven-compiler-plugin
154 | 3.8.1
155 |
156 | 1.8
157 | 1.8
158 |
159 |
160 |
161 | org.apache.maven.plugins
162 | maven-release-plugin
163 | 2.4.2
164 |
165 |
166 | org.apache.maven.scm
167 | maven-scm-provider-gitexe
168 | 1.8.1
169 |
170 |
171 |
172 |
173 | org.apache.maven.plugins
174 | maven-source-plugin
175 | 2.2.1
176 |
177 |
178 | attach-sources
179 |
180 | jar
181 |
182 |
183 |
184 |
185 |
186 | org.apache.maven.plugins
187 | maven-javadoc-plugin
188 | 2.9.1
189 |
190 |
191 | attach-javadocs
192 |
193 | jar
194 |
195 |
196 |
197 |
198 |
199 | org.apache.maven.plugins
200 | maven-assembly-plugin
201 | 3.1.1
202 |
203 |
204 | jar-with-dependencies
205 |
206 |
207 |
208 |
209 | make-assembly
210 | package
211 |
212 | single
213 |
214 |
215 |
216 |
217 |
218 |
219 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file.
3 |
4 | This project adheres to [Semantic Versioning](http://semver.org/).
5 |
6 | [2022-05-18] Version 4.5.1
7 | --------------------------
8 | **Library - Docs**
9 | - [PR #144](https://github.com/sendgrid/java-http-client/pull/144): Update to align with SendGrid Support. Thanks to [@garethpaul](https://github.com/garethpaul)!
10 |
11 | **Library - Fix**
12 | - [PR #143](https://github.com/sendgrid/java-http-client/pull/143): override default gh token. Thanks to [@beebzz](https://github.com/beebzz)!
13 |
14 |
15 | [2022-03-09] Version 4.5.0
16 | --------------------------
17 | **Library - Chore**
18 | - [PR #142](https://github.com/sendgrid/java-http-client/pull/142): push Datadog Release Metric upon deploy success. Thanks to [@eshanholtz](https://github.com/eshanholtz)!
19 |
20 | **Library - Feature**
21 | - [PR #141](https://github.com/sendgrid/java-http-client/pull/141): add GH action to update dependencies. Thanks to [@JenniferMah](https://github.com/JenniferMah)!
22 |
23 |
24 | [2022-02-09] Version 4.4.0
25 | --------------------------
26 | **Library - Chore**
27 | - [PR #139](https://github.com/sendgrid/java-http-client/pull/139): upgrade supported language versions. Thanks to [@childish-sambino](https://github.com/childish-sambino)!
28 | - [PR #138](https://github.com/sendgrid/java-http-client/pull/138): add gh release to workflow. Thanks to [@shwetha-manvinkurke](https://github.com/shwetha-manvinkurke)!
29 | - [PR #137](https://github.com/sendgrid/java-http-client/pull/137): merge test and deploy workflows. Thanks to [@shwetha-manvinkurke](https://github.com/shwetha-manvinkurke)!
30 |
31 | **Library - Feature**
32 | - [PR #134](https://github.com/sendgrid/java-http-client/pull/134): Support multiple duplicate queryparams. Thanks to [@mjjs](https://github.com/mjjs)!
33 |
34 |
35 | [2022-01-12] Version 4.3.9
36 | --------------------------
37 | **Library - Chore**
38 | - [PR #136](https://github.com/sendgrid/java-http-client/pull/136): update license year. Thanks to [@JenniferMah](https://github.com/JenniferMah)!
39 |
40 |
41 | [2021-12-01] Version 4.3.8
42 | --------------------------
43 | **Library - Chore**
44 | - [PR #135](https://github.com/sendgrid/java-http-client/pull/135): fix pom for release. Thanks to [@eshanholtz](https://github.com/eshanholtz)!
45 | - [PR #133](https://github.com/sendgrid/java-http-client/pull/133): migrate to github actions. Thanks to [@eshanholtz](https://github.com/eshanholtz)!
46 |
47 |
48 | [2021-05-19] Version 4.3.7
49 | --------------------------
50 | **Library - Chore**
51 | - [PR #131](https://github.com/sendgrid/java-http-client/pull/131): Bump org.apache.httpcomponents.httpclient from 4.5.12 to 4.5.13. Thanks to [@akunzai](https://github.com/akunzai)!
52 |
53 |
54 | [2020-08-19] Version 4.3.6
55 | --------------------------
56 | **Library - Chore**
57 | - [PR #128](https://github.com/sendgrid/java-http-client/pull/128): update GitHub branch references to use HEAD. Thanks to [@thinkingserious](https://github.com/thinkingserious)!
58 |
59 | **Library - Docs**
60 | - [PR #97](https://github.com/sendgrid/java-http-client/pull/97): Correcting *.md files using Grammarly. Thanks to [@pushkyn](https://github.com/pushkyn)!
61 | - [PR #101](https://github.com/sendgrid/java-http-client/pull/101): Add first timers file. Thanks to [@Varpie](https://github.com/Varpie)!
62 |
63 |
64 | [2020-08-05] Version 4.3.5
65 | --------------------------
66 | **Library - Docs**
67 | - [PR #86](https://github.com/sendgrid/java-http-client/pull/86): Moved usage and enviorment variables to USAGE.md. Thanks to [@rareinator](https://github.com/rareinator)!
68 |
69 |
70 | [2020-07-22] Version 4.3.4
71 | --------------------------
72 | **Library - Fix**
73 | - [PR #109](https://github.com/sendgrid/java-http-client/pull/109): correct the LICENSE.md link in pom.xml. Thanks to [@crweiner](https://github.com/crweiner)!
74 |
75 | **Library - Docs**
76 | - [PR #108](https://github.com/sendgrid/java-http-client/pull/108): Create a Use Cases Directory. Thanks to [@ajloria](https://github.com/ajloria)!
77 |
78 |
79 | [2020-03-04] Version 4.3.3
80 | --------------------------
81 | **Library - Chore**
82 | - [PR #127](https://github.com/sendgrid/java-http-client/pull/127): fix JDK Travis failures. Thanks to [@childish-sambino](https://github.com/childish-sambino)!
83 |
84 |
85 | [2020-02-19] Version 4.3.2
86 | --------------------------
87 | **Library - Chore**
88 | - [PR #111](https://github.com/sendgrid/java-http-client/pull/111): Update the Client file documentation. Thanks to [@vinifarias](https://github.com/vinifarias)!
89 |
90 |
91 | [2020-02-05] Version 4.3.1
92 | --------------------------
93 | **Library - Docs**
94 | - [PR #126](https://github.com/sendgrid/java-http-client/pull/126): baseline all the templated markdown docs. Thanks to [@childish-sambino](https://github.com/childish-sambino)!
95 |
96 |
97 | [2020-02-01] Version 4.3.0
98 | --------------------------
99 | **Library - Feature**
100 | - [PR #25](https://github.com/sendgrid/java-http-client/pull/25): do not close or manage lifecycle of http-client passed in. Thanks to [@maxxedev](https://github.com/maxxedev)!
101 | - [PR #34](https://github.com/sendgrid/java-http-client/pull/34): Add close method to Client. Thanks to [@tsuyoshizawa](https://github.com/tsuyoshizawa)!
102 | - [PR #67](https://github.com/sendgrid/java-http-client/pull/67): Adding Docker support. Thanks to [@mithunsasidharan](https://github.com/mithunsasidharan)!
103 |
104 | **Library - Fix**
105 | - [PR #26](https://github.com/sendgrid/java-http-client/pull/26): use .equals to compare strings. Thanks to [@maxxedev](https://github.com/maxxedev)!
106 | - [PR #36](https://github.com/sendgrid/java-http-client/pull/36): No longer throwing IOExceptions on non 2xx response codes. Thanks to [@andy-trimble](https://github.com/andy-trimble)!
107 | - [PR #77](https://github.com/sendgrid/java-http-client/pull/77): Closes #72 Update Example.java. Thanks to [@AbdulDroid](https://github.com/AbdulDroid)!
108 |
109 | **Library - Chore**
110 | - [PR #54](https://github.com/sendgrid/java-http-client/pull/54): Added example file, updated .gitignore and README. Thanks to [@dhsrocha](https://github.com/dhsrocha)!
111 | - [PR #58](https://github.com/sendgrid/java-http-client/pull/58): added .codeclimate,yml for codeclimate run. Thanks to [@skshelar](https://github.com/skshelar)!
112 | - [PR #73](https://github.com/sendgrid/java-http-client/pull/73): Fixes #71. Thanks to [@huytranrjc](https://github.com/huytranrjc)!
113 | - [PR #76](https://github.com/sendgrid/java-http-client/pull/76): Update travis - add codecov. Thanks to [@pushkyn](https://github.com/pushkyn)!
114 | - [PR #92](https://github.com/sendgrid/java-http-client/pull/92): update LICENSE - bump year. Thanks to [@pushkyn](https://github.com/pushkyn)!
115 | - [PR #115](https://github.com/sendgrid/java-http-client/pull/115): add [openjdk11] to Travis build. Thanks to [@sullis](https://github.com/sullis)!
116 | - [PR #117](https://github.com/sendgrid/java-http-client/pull/117): Update transitive dependencies. Thanks to [@kebeda](https://github.com/kebeda)!
117 | - [PR #123](https://github.com/sendgrid/java-http-client/pull/123): prep the repo for automated releases. Thanks to [@eshanholtz](https://github.com/eshanholtz)!
118 |
119 | **Library - Docs**
120 | - [PR #59](https://github.com/sendgrid/java-http-client/pull/59): Typos in CONTRIBUTING.md. Thanks to [@rkaranam](https://github.com/rkaranam)!
121 | - [PR #113](https://github.com/sendgrid/java-http-client/pull/113): Add our Developer Experience Engineer career opportunity to the READM…. Thanks to [@mptap](https://github.com/mptap)!
122 |
123 | **Library - Test**
124 | - [PR #66](https://github.com/sendgrid/java-http-client/pull/66): Test to check year in license file. Thanks to [@pushkyn](https://github.com/pushkyn)!
125 | - [PR #93](https://github.com/sendgrid/java-http-client/pull/93): removed tests that were testing for files that didnt exist, bumped gradle version to 4.10.2. Thanks to [@Strum355](https://github.com/Strum355)!
126 |
127 |
128 | [2017-10-30] Version 4.2.0
129 | ---------------------------
130 | ### Added
131 | - [Pull #22](https://github.com/sendgrid/java-http-client/pull/22): Allow setting both `apache http client` and `test` parameters
132 | - BIG thanks to [Maxim Novak](https://github.com/maximn) for the pull request!
133 |
134 | ## [4.1.1] - 2016-10-11
135 | ### Added
136 | - [Pull #23](https://github.com/sendgrid/java-http-client/pull/23): Moved Mockito to test dependency.
137 | - BIG thanks to [Joseph Lust](https://github.com/twistedpair) for the pull request!
138 |
139 | ## [4.1.0] - 2016-10-11
140 | ### Added
141 | - [Pull #17](https://github.com/sendgrid/java-http-client/pull/17): Assign server response outside try block
142 | - BIG thanks to [Michael Dempsey](https://github.com/bluestealth) for the pull request!
143 |
144 | ## [4.0.0] - 2016-10-11
145 | ### BREAKING Change
146 | - [Pull #14](https://github.com/sendgrid/java-http-client/pull/14): Make response have private variables
147 | - Fixed [Issue #12](https://github.com/sendgrid/java-http-client/issues/12): The public Response variables should be private
148 | - The breaking change is that variables that were public are now private and accessible only via getters and setters
149 | - BIG thanks to [Diego Camargo](https://github.com/belfazt) for the pull request!
150 |
151 | ## [3.0.0] - 2016-10-06
152 | ### BREAKING Change
153 | - [Pull #15](https://github.com/sendgrid/java-http-client/pull/15): Update the request object with sensible defaults and access methods
154 | - Fixes [Issue #13](https://github.com/sendgrid/java-http-client/issues/13): Update the Request object with sensible defaults and access methods
155 | - The breaking change is that variables that were public are now private and accessible only via getters and setters
156 | - BIG thanks to [Diego Camargo](https://github.com/belfazt) for the pull request!
157 |
158 | ## [2.3.4] - 2016-08-09
159 | ### Fix
160 | - [Pull #7](https://github.com/sendgrid/java-http-client/pull/7): Fix Response Charset to UTF-8
161 | - Fixes [issue #6](https://github.com/sendgrid/java-http-client/issues/6): Multi-byte character got garbled on received mail
162 | - BIG thanks to [Yoichi Kikuta](https://github.com/kikutaro) for the pull request!
163 |
164 | ## [2.3.3] - 2016-08-08
165 | ### Added
166 | - Pull request [#11](https://github.com/sendgrid/java-http-client/pull/11)
167 | - Solves [issue #10](https://github.com/sendgrid/java-http-client/issues/10): Improve Error Handling
168 | - Now error messages are passed through from the server
169 | - BIG thanks to [shuron](https://github.com/shuron) / [Alexander Holbreich](https://github.com/aholbreich) for the pull request!
170 |
171 | ## [2.3.2] - 2016-07-18
172 | ### Fixed
173 | - 2.3.1 did not upload correctly
174 |
175 | ## [2.3.1] - 2016-07-08
176 | ### Fixed
177 | - [Fix charset: Use "UTF-8" charset instead of default "ISO-8859-1"](https://github.com/sendgrid/java-http-client/pull/5)
178 | - Thanks [DanailMinchev](https://github.com/DanailMinchev)!
179 |
180 | ## [2.3.0] - 2016-06-10
181 | ### Added
182 | - Automatically add Content-Type: application/json when there is a request body
183 |
184 | ## [2.2.1] - 2016-06-08
185 | ### Fixed
186 | - Set client properly when testing
187 |
188 | ## [2.2.0] - 2016-06-08
189 | ### Added
190 | - Can pass test flag to allow for http calls
191 |
192 | ## [2.1.0] - 2016-06-08
193 | ### Added
194 | - DELETE can now have a request body
195 |
196 | ## [2.0.0] - 2016-06-03
197 | ### Changed
198 | - Made the Request and Response variables non-redundant. e.g. request.requestBody becomes request.body
199 |
200 | ## [1.0.0] - 2016-04-15
201 | ### Added
202 | - We are live!
203 |
--------------------------------------------------------------------------------
/src/main/java/com/sendgrid/Client.java:
--------------------------------------------------------------------------------
1 | package com.sendgrid;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 | import java.io.PrintWriter;
6 | import java.io.StringWriter;
7 | import java.net.URI;
8 | import java.net.URISyntaxException;
9 | import java.nio.charset.Charset;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 | import org.apache.http.Header;
16 | import org.apache.http.HttpMessage;
17 | import org.apache.http.client.ClientProtocolException;
18 | import org.apache.http.client.ResponseHandler;
19 | import org.apache.http.client.methods.CloseableHttpResponse;
20 | import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
21 | import org.apache.http.client.methods.HttpGet;
22 | import org.apache.http.client.methods.HttpPatch;
23 | import org.apache.http.client.methods.HttpPost;
24 | import org.apache.http.client.methods.HttpPut;
25 | import org.apache.http.client.methods.HttpRequestBase;
26 | import org.apache.http.client.utils.URIBuilder;
27 | import org.apache.http.entity.StringEntity;
28 | import org.apache.http.impl.client.CloseableHttpClient;
29 | import org.apache.http.impl.client.HttpClients;
30 |
31 |
32 | /**
33 | * Hack to get DELETE to accept a request body.
34 | */
35 | class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
36 | public static final String METHOD_NAME = "DELETE";
37 |
38 | @Override
39 | public String getMethod() {
40 | return METHOD_NAME;
41 | }
42 |
43 | public HttpDeleteWithBody(final String uri) {
44 | super();
45 | setURI(URI.create(uri));
46 | }
47 | }
48 |
49 |
50 | /**
51 | * Class Client allows for quick and easy access any REST or REST-like API.
52 | */
53 | public class Client implements Closeable {
54 |
55 | private CloseableHttpClient httpClient;
56 | private Boolean test;
57 | private boolean createdHttpClient;
58 |
59 |
60 | /**
61 | * Constructor for using the default CloseableHttpClient.
62 | */
63 | public Client() {
64 | this.httpClient = HttpClients.createDefault();
65 | this.test = false;
66 | this.createdHttpClient = true;
67 | }
68 |
69 |
70 | /**
71 | * Constructor for passing in an httpClient, typically for mocking. Passed-in httpClient will not be closed
72 | * by this Client.
73 | *
74 | * @param httpClient
75 | * an Apache CloseableHttpClient
76 | */
77 | public Client(CloseableHttpClient httpClient) {
78 | this(httpClient, false);
79 | }
80 |
81 |
82 | /**
83 | * Constructor for passing in a test parameter to allow for http calls.
84 | *
85 | * @param test
86 | * is a Bool
87 | */
88 | public Client(Boolean test) {
89 | this(HttpClients.createDefault(), test);
90 | }
91 |
92 |
93 | /**
94 | * Constructor for passing in an httpClient and test parameter to allow for http calls.
95 | *
96 | * @param httpClient
97 | * an Apache CloseableHttpClient
98 | * @param test
99 | * is a Bool
100 | */
101 | public Client(CloseableHttpClient httpClient, Boolean test) {
102 | this.httpClient = httpClient;
103 | this.test = test;
104 | this.createdHttpClient = true;
105 | }
106 |
107 |
108 | /**
109 | * Add query parameters to a URL.
110 | *
111 | * @param baseUri
112 | * (e.g. "api.sendgrid.com")
113 | * @param endpoint
114 | * (e.g. "/your/endpoint/path")
115 | * @param queryParams
116 | * map of key, values representing the query parameters
117 | * @throws URISyntaxException
118 | * in of a URI syntax error
119 | */
120 | public URI buildUri(String baseUri, String endpoint, Map queryParams) throws URISyntaxException {
121 | URIBuilder builder = new URIBuilder();
122 | URI uri = null;
123 |
124 | if (this.test == true) {
125 | builder.setScheme("http");
126 | } else {
127 | builder.setScheme("https");
128 | }
129 |
130 | builder.setHost(baseUri);
131 | builder.setPath(endpoint);
132 |
133 | if (queryParams != null) {
134 | String multiValueDelimiter = "&";
135 |
136 | for (Map.Entry entry : queryParams.entrySet()) {
137 | String value = entry.getValue();
138 |
139 | if (value.indexOf(multiValueDelimiter) != -1) {
140 | List values = Arrays.asList(value.split(multiValueDelimiter));
141 | for (String val : values) {
142 | builder.addParameter(entry.getKey(), val);
143 | }
144 | } else {
145 | builder.setParameter(entry.getKey(), entry.getValue());
146 | }
147 | }
148 | }
149 |
150 | try {
151 | uri = builder.build();
152 | } catch (URISyntaxException ex) {
153 | throw ex;
154 | }
155 |
156 | return uri;
157 | }
158 |
159 |
160 | /**
161 | * Prepare a Response object from an API call via Apache's HTTP client.
162 | *
163 | * @param response
164 | * from a call to a CloseableHttpClient
165 | * @throws IOException
166 | * in case of a network error
167 | * @return the response object
168 | */
169 | public Response getResponse(CloseableHttpResponse response) throws IOException {
170 | ResponseHandler handler = new SendGridResponseHandler();
171 | String responseBody = handler.handleResponse(response);
172 |
173 | int statusCode = response.getStatusLine().getStatusCode();
174 |
175 | Header[] headers = response.getAllHeaders();
176 | Map responseHeaders = new HashMap();
177 | for (Header h : headers) {
178 | responseHeaders.put(h.getName(), h.getValue());
179 | }
180 |
181 | return new Response(statusCode, responseBody, responseHeaders);
182 | }
183 |
184 |
185 | /**
186 | * Make a GET request and provide the status code, response body and
187 | * response headers.
188 | *
189 | * @param request
190 | * the request object
191 | * @throws URISyntaxException
192 | * in case of a URI syntax error
193 | * @throws IOException
194 | * in case of a network error
195 | * @return the response object
196 | */
197 | public Response get(Request request) throws URISyntaxException, IOException {
198 | URI uri = null;
199 | HttpGet httpGet = null;
200 |
201 | try {
202 | uri = buildUri(request.getBaseUri(), request.getEndpoint(), request.getQueryParams());
203 | httpGet = new HttpGet(uri.toString());
204 | } catch (URISyntaxException ex) {
205 | throw ex;
206 | }
207 |
208 | if (request.getHeaders() != null) {
209 | for (Map.Entry entry : request.getHeaders().entrySet()) {
210 | httpGet.setHeader(entry.getKey(), entry.getValue());
211 | }
212 | }
213 | return executeApiCall(httpGet);
214 | }
215 |
216 |
217 | /**
218 | * Make a POST request and provide the status code, response body and
219 | * response headers.
220 | *
221 | * @param request
222 | * the request object
223 | * @throws URISyntaxException
224 | * in case of a URI syntax error
225 | * @throws IOException
226 | * in case of a network error
227 | * @return the response object
228 | */
229 | public Response post(Request request) throws URISyntaxException, IOException {
230 | URI uri = null;
231 | HttpPost httpPost = null;
232 |
233 | try {
234 | uri = buildUri(request.getBaseUri(), request.getEndpoint(), request.getQueryParams());
235 | httpPost = new HttpPost(uri.toString());
236 | } catch (URISyntaxException ex) {
237 | throw ex;
238 | }
239 |
240 | if (request.getHeaders() != null) {
241 | for (Map.Entry entry : request.getHeaders().entrySet()) {
242 | httpPost.setHeader(entry.getKey(), entry.getValue());
243 | }
244 | }
245 |
246 | httpPost.setEntity(new StringEntity(request.getBody(), Charset.forName("UTF-8")));
247 | writeContentTypeIfNeeded(request, httpPost);
248 |
249 | return executeApiCall(httpPost);
250 | }
251 |
252 |
253 | /**
254 | * Make a PATCH request and provide the status code, response body and
255 | * response headers.
256 | *
257 | * @param request
258 | * the request object
259 | * @throws URISyntaxException
260 | * in case of a URI syntax error
261 | * @throws IOException
262 | * in case of a network error
263 | * @return the response object
264 | */
265 | public Response patch(Request request) throws URISyntaxException, IOException {
266 | URI uri = null;
267 | HttpPatch httpPatch = null;
268 |
269 | try {
270 | uri = buildUri(request.getBaseUri(), request.getEndpoint(), request.getQueryParams());
271 | httpPatch = new HttpPatch(uri.toString());
272 | } catch (URISyntaxException ex) {
273 | throw ex;
274 | }
275 |
276 | if (request.getHeaders() != null) {
277 | for (Map.Entry entry : request.getHeaders().entrySet()) {
278 | httpPatch.setHeader(entry.getKey(), entry.getValue());
279 | }
280 | }
281 |
282 | httpPatch.setEntity(new StringEntity(request.getBody(), Charset.forName("UTF-8")));
283 | writeContentTypeIfNeeded(request, httpPatch);
284 |
285 | return executeApiCall(httpPatch);
286 | }
287 |
288 |
289 | /**
290 | * Make a PUT request and provide the status code, response body and
291 | * response headers.
292 | *
293 | * @param request
294 | * the request object
295 | * @throws URISyntaxException
296 | * in case of a URI syntax error
297 | * @throws IOException
298 | * in case of a network error
299 | * @return the response object
300 | */
301 | public Response put(Request request) throws URISyntaxException, IOException {
302 | URI uri = null;
303 | HttpPut httpPut = null;
304 |
305 | try {
306 | uri = buildUri(request.getBaseUri(), request.getEndpoint(), request.getQueryParams());
307 | httpPut = new HttpPut(uri.toString());
308 | } catch (URISyntaxException ex) {
309 | throw ex;
310 | }
311 |
312 | if (request.getHeaders() != null) {
313 | for (Map.Entry entry : request.getHeaders().entrySet()) {
314 | httpPut.setHeader(entry.getKey(), entry.getValue());
315 | }
316 | }
317 |
318 | httpPut.setEntity(new StringEntity(request.getBody(), Charset.forName("UTF-8")));
319 | writeContentTypeIfNeeded(request, httpPut);
320 |
321 | return executeApiCall(httpPut);
322 | }
323 |
324 |
325 | /**
326 | * Make a DELETE request and provide the status code and response headers.
327 | *
328 | * @param request
329 | * the request object
330 | * @throws URISyntaxException
331 | * in case of a URI syntax error
332 | * @throws IOException
333 | * in case of a network error
334 | * @return the response object
335 | */
336 | public Response delete(Request request) throws URISyntaxException, IOException {
337 | URI uri = null;
338 | HttpDeleteWithBody httpDelete = null;
339 |
340 | try {
341 | uri = buildUri(request.getBaseUri(), request.getEndpoint(), request.getQueryParams());
342 | httpDelete = new HttpDeleteWithBody(uri.toString());
343 | } catch (URISyntaxException ex) {
344 | throw ex;
345 | }
346 |
347 | if (request.getHeaders() != null) {
348 | for (Map.Entry entry : request.getHeaders().entrySet()) {
349 | httpDelete.setHeader(entry.getKey(), entry.getValue());
350 | }
351 | }
352 |
353 | httpDelete.setEntity(new StringEntity(request.getBody(), Charset.forName("UTF-8")));
354 | writeContentTypeIfNeeded(request, httpDelete);
355 |
356 | return executeApiCall(httpDelete);
357 | }
358 |
359 | private void writeContentTypeIfNeeded(Request request, HttpMessage httpMessage) {
360 | if (!"".equals(request.getBody())) {
361 | httpMessage.setHeader("Content-Type", "application/json");
362 | }
363 | }
364 |
365 |
366 | /**
367 | * Makes a call to the client API.
368 | *
369 | * @param httpPost
370 | * the request method object
371 | * @throws IOException
372 | * in case of a network error
373 | * @return the response object
374 | */
375 | private Response executeApiCall(HttpRequestBase httpPost) throws IOException {
376 | try {
377 | CloseableHttpResponse serverResponse = httpClient.execute(httpPost);
378 | try {
379 | return getResponse(serverResponse);
380 | } finally {
381 | serverResponse.close();
382 | }
383 | } catch(ClientProtocolException e) {
384 | throw new IOException(e.getMessage());
385 | }
386 | }
387 |
388 |
389 | /**
390 | * A thin wrapper around the HTTP methods.
391 | *
392 | * @param request
393 | * the request object
394 | * @throws IOException
395 | * in case of a network error
396 | * @return the response object
397 | */
398 | public Response api(Request request) throws IOException {
399 | try {
400 | if (request.getMethod() == null) {
401 | throw new IOException("We only support GET, PUT, PATCH, POST and DELETE.");
402 | }
403 | switch (request.getMethod()) {
404 | case GET:
405 | return get(request);
406 | case POST:
407 | return post(request);
408 | case PUT:
409 | return put(request);
410 | case PATCH:
411 | return patch(request);
412 | case DELETE:
413 | return delete(request);
414 | default:
415 | throw new IOException("We only support GET, PUT, PATCH, POST and DELETE.");
416 | }
417 | } catch (IOException ex) {
418 | throw ex;
419 | } catch (URISyntaxException ex) {
420 | StringWriter errors = new StringWriter();
421 | ex.printStackTrace(new PrintWriter(errors));
422 | throw new IOException(errors.toString());
423 | }
424 | }
425 |
426 |
427 | /**
428 | * Closes the http client.
429 | *
430 | * @throws IOException
431 | * in case of a network error
432 | */
433 | @Override
434 | public void close() throws IOException {
435 | this.httpClient.close();
436 | }
437 |
438 |
439 | /**
440 | * Closes and finalizes the http client.
441 | *
442 | * @throws Throwable
443 | * in case of an error
444 | */
445 | @Override
446 | public void finalize() throws Throwable {
447 | try {
448 | close();
449 | } catch(IOException e) {
450 | throw new Throwable(e.getMessage());
451 | } finally {
452 | super.finalize();
453 | }
454 | }
455 | }
456 |
--------------------------------------------------------------------------------