com.hulaki.smtp.api.ApiClient.java Source code

Java tutorial

Introduction

Here is the source code for com.hulaki.smtp.api.ApiClient.java

Source

/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hulaki.smtp.api;

import com.hulaki.smtp.exceptions.ApiException;
import com.hulaki.smtp.exceptions.SmtpTimeoutException;
import com.hulaki.smtp.utils.EmailUtils;
import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.Socket;
import java.util.List;

public class ApiClient implements IApiClient {
    private final Logger logger = Logger.getLogger(ApiClient.class);
    private final long DEFAULT_TIMEOUT_IN_MILLIS = 8000L;
    private final long MAX_NUM_OF_TIMES_TO_POLL = 8;
    private final String apiServerHostname;
    private final int apiServerPort;

    public ApiClient(String apiServerHostname, int apiServerPort) {
        this.apiServerHostname = apiServerHostname;
        this.apiServerPort = apiServerPort;
    }

    @Override
    public void waitForNewEmailOrFail(String recipient, int oldEmailCount) throws InterruptedException {
        waitForNewEmailOrFail(recipient, oldEmailCount, DEFAULT_TIMEOUT_IN_MILLIS);
    }

    @Override
    public void waitForNewEmailOrFail(String recipient, int oldEmailCount, long timeoutInMillis)
            throws InterruptedException {

        long sleepTime = timeoutInMillis / MAX_NUM_OF_TIMES_TO_POLL;
        int newEmailCount = countMails(recipient);
        int pollCounter = 0;
        while (newEmailCount <= oldEmailCount && pollCounter < MAX_NUM_OF_TIMES_TO_POLL) {
            pollCounter++;
            Thread.sleep(sleepTime);
            newEmailCount = countMails(recipient);
        }
        if (newEmailCount <= oldEmailCount) {
            throw new SmtpTimeoutException("No new mail was received for " + recipient);
        }
    }

    @Override
    public int countMails() {
        logger.debug("Counting ALL emails stored on the server...");
        CountRequest countRequest = new CountRequest();
        String response = sendRequestToApiServer(countRequest);
        CountResponse cResponse = unmarshalResponse(response, CountResponse.class);
        logger.debug("Counted " + cResponse.getCount() + " emails");
        return cResponse.getCount();
    }

    @Override
    public int countMails(String recipient) {
        Assert.notNull(recipient);

        logger.debug("Counting emails for recipient: " + recipient + "...");
        CountRequest countRequest = new CountRequest();
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        countRequest.setRecipient(normalizedEmail);

        String response = sendRequestToApiServer(countRequest);
        CountResponse cResponse = unmarshalResponse(response, CountResponse.class);
        logger.debug("Counted " + cResponse.getCount() + " emails sent to " + recipient);
        return cResponse.getCount();
    }

    @Override
    public void clearMails(String recipient) {
        logger.debug("Clearing emails for recipient: " + recipient + "...");
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        ClearRequest clearRequest = new ClearRequest().setRecipient(normalizedEmail);

        String response = sendRequestToApiServer(clearRequest);
        StatusResponse sResponse = unmarshalResponse(response, StatusResponse.class);
        assert (sResponse.getStatus() == 200);
        logger.debug("All emails cleared for recipient: " + recipient);
    }

    @Override
    public List<MailMessage> getMessages(String recipient) {
        logger.debug("Retrieving emails for recipient: " + recipient + "...");
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        GetRequest getRequest = new GetRequest().setRecipient(normalizedEmail);

        String response;
        response = sendRequestToApiServer(getRequest);

        GetResponse getResponse = unmarshalResponse(response, GetResponse.class);
        logger.debug("Retrieved " + getResponse.getMessages().size() + " emails for recipient: " + recipient);
        return getResponse.getMessages();
    }

    @Override
    public boolean isRelayRecipient(String recipient) {
        logger.debug("Checking if " + recipient + " is a relay recipient...");
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        RelayRequest relayRequest = new RelayRequest(RelayMode.GET);
        relayRequest.setRecipient(normalizedEmail);
        String response = sendRequestToApiServer(relayRequest);
        StatusResponse statusResponse = unmarshalResponse(response, StatusResponse.class);
        boolean isRelayRecipient = statusResponse.getStatus() == 200;
        logger.debug(recipient + ((isRelayRecipient) ? " is" : " isn't") + " a relay recipient");
        return isRelayRecipient;
    }

    @Override
    public void addRelayRecipient(String recipient) {
        logger.debug("Making " + recipient + " a relay recipient...");
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        RelayRequest relayRequest = new RelayRequest(RelayMode.ADD);
        relayRequest.setRecipient(normalizedEmail);
        String response = sendRequestToApiServer(relayRequest);
        StatusResponse statusResponse = unmarshalResponse(response, StatusResponse.class);
        assert (statusResponse.getStatus() == 200);
        logger.debug(recipient + " is now a relay recipient.");
    }

    @Override
    public void removeRelayRecipient(String recipient) {
        logger.debug("Removing " + recipient + " from list of relay recipients...");
        String normalizedEmail = EmailUtils.normalizeEmailAddress(recipient);
        RelayRequest relayRequest = new RelayRequest(RelayMode.REMOVE);
        relayRequest.setRecipient(normalizedEmail);
        String response = sendRequestToApiServer(relayRequest);
        StatusResponse statusResponse = unmarshalResponse(response, StatusResponse.class);
        assert (statusResponse.getStatus() == 200);
        logger.debug(recipient + " is no more a relay recipient.");
    }

    @Override
    public void clearRelayRecipients() {
        logger.debug("Removing ALL relay recipients...");
        RelayRequest relayRequest = new RelayRequest(RelayMode.REMOVE);
        String response = sendRequestToApiServer(relayRequest);
        StatusResponse statusResponse = unmarshalResponse(response, StatusResponse.class);
        assert (statusResponse.getStatus() == 200);
        logger.debug("Relay recipient list cleared.");
    }

    @Override
    public List<String> getRelayRecipients() {
        logger.debug("Retrieving the list of relay recipients...");
        RelayRequest relayRequest = new RelayRequest(RelayMode.GET);
        String response = sendRequestToApiServer(relayRequest);
        RelayResponse relayResponse = unmarshalResponse(response, RelayResponse.class);
        logger.debug("Currently " + relayResponse.getRelayRecipients().getRecipients().size()
                + " relay recipieints are registered.");
        return relayResponse.getRelayRecipients().getRecipients();
    }

    @SuppressWarnings("unchecked")
    private <T> T unmarshalResponse(String response, Class<T> clazz) {
        try {
            return (T) ApiResponse.unmarshalResponse(response, clazz);
        } catch (Exception ioe) {
            throw new ApiException(ioe);
        }
    }

    private String sendRequestToApiServer(ApiRequest request) {
        try {
            Socket clientSocket = new Socket(this.apiServerHostname, this.apiServerPort);
            DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());

            String requestString = request.toRequestString() + "\n";
            logger.trace(requestString);
            out.writeBytes(requestString);
            StringBuilder response = new StringBuilder();
            logger.trace(response.toString());

            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine).append("\n");
            }
            clientSocket.close();
            return response.toString();
        } catch (ConnectException e) {
            throw new ApiException("SMTP mock not available at " + apiServerHostname + ":" + apiServerPort);
        } catch (IOException e) {
            throw new ApiException(e);
        }
    }
}