de.elomagic.mag.RouteBuilderFactory.java Source code

Java tutorial

Introduction

Here is the source code for de.elomagic.mag.RouteBuilderFactory.java

Source

/*
 * Mail Attachment Gateway
 * Copyright (c) 2016-2017 Carsten Rambow
 * mailto:developer AT elomagic DOT de
 *
 * 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 de.elomagic.mag;

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;

import com.google.api.services.drive.DriveScopes;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.google.drive.GoogleDriveComponent;
import org.apache.camel.component.google.drive.GoogleDriveConfiguration;
import org.apache.camel.component.google.drive.internal.DriveFilesApiMethod;
import org.apache.camel.component.google.drive.internal.GoogleDriveApiCollection;
import org.apache.camel.model.ExpressionNode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.util.StringUtils;
import org.mortbay.jetty.HttpHeaders;
import org.mortbay.jetty.HttpMethods;

import de.elomagic.mag.Configuration.ConfigurationKey;
import de.elomagic.mag.expressions.SplitAttachmentsExpression;
import de.elomagic.mag.google.BatchGoogleDriveClientFactory;
import de.elomagic.mag.processors.PrepareGoogleDriveFileCreateProcessor;
import de.elomagic.mag.processors.PrepareNotificationMailProcessor;

/**
 *
 * @author Carsten Rambow
 */
public final class RouteBuilderFactory {

    private static final String LOG_ROUTE_PREFIX = "log:de.elomagic.mag.route.";

    private static final Logger LOGGER = LogManager.getLogger(RouteBuilderFactory.class);

    private RouteBuilderFactory() {
    }

    public static RouteBuilder createRoute(final CamelContext context) {

        return new RouteBuilder() {
            @Override
            public void configure() {

                LOGGER.debug("Creating Camel routes...");

                NotificationCounter notificationCounter = new NotificationCounter(); //context.addComponent("notificationCounter", new NotificationCounter());                

                if (!"".equals(Configuration.get(ConfigurationKey.MailNotificationFailedRecipient))) {
                    onException(Exception.class).to("direct:failed");
                }

                ExpressionNode node = from(getMailInputUri()).routeId("mail-input-route")
                        .to(LOG_ROUTE_PREFIX + "from").split(new SplitAttachmentsExpression());

                if (Configuration.get(ConfigurationKey.TargetFileSystemEnabled, Boolean.class)) {
                    node = node.to(LOG_ROUTE_PREFIX + "filesystem")
                            .setHeader("CamelFileName", header(Constants.HEADER_FILENAME)).to(getFileSystemUri());
                }

                if (Configuration.get(ConfigurationKey.TargetSmbEnabled, Boolean.class)) {
                    node = node.to(LOG_ROUTE_PREFIX + "smb")
                            .setHeader("CamelFileName", header(Constants.HEADER_FILENAME)).to(getSmbUri());
                }

                if (Configuration.get(ConfigurationKey.TargetWebDAVEnabled, Boolean.class)) {
                    String s = Configuration.get(ConfigurationKey.TargetWebDAVUsername) + ":"
                            + Configuration.get(ConfigurationKey.TargetWebDAVPassword);
                    String hash = Base64.getEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8));
                    // Authorization: Basic am9obi5kb2U6c2VjcmV0

                    String uri = Configuration.get(ConfigurationKey.TargetWebDAVUrl) + "${header."
                            + Constants.HEADER_ALTERNATIVE_FILENAME + "}";

                    node = node.to(LOG_ROUTE_PREFIX + "webdav-put")
                            .setHeader(HttpHeaders.AUTHORIZATION, constant("Basic " + hash))
                            .setHeader(Exchange.HTTP_URI, simple(uri))
                            .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.PUT)).to(getWebDAVUri(context));
                }

                if (Configuration.get(ConfigurationKey.TargetGoogleDriveEnabled, Boolean.class)) {
                    node = node.to(LOG_ROUTE_PREFIX + "googledrive")
                            .process(new PrepareGoogleDriveFileCreateProcessor())
                            .to(getGoogleDriveUploadFileUri(context));
                }

                node.bean(notificationCounter, "incrementSuccess").end();

                // Notification timer
                from("scheduler:notificationTimer" + "?timeUnit=SECONDS" + "&delay=60" + "&initialDelay=10")
                        .setHeader("AttachmentSuccess", method(notificationCounter, "getSuccess")).filter()
                        .method(notificationCounter, "isSuccessAndClear").to("direct:success");

                // Notification route for failed proceed messages
                if (!"".equals(Configuration.get(ConfigurationKey.MailNotificationFailedRecipient))) {
                    from("direct:failed").routeId("mail-notification-on-failed")
                            .filter(constant(Configuration.get(ConfigurationKey.MailNotificationFailedRecipient))
                                    .isNotEqualTo(""))
                            .process(new PrepareNotificationMailProcessor())
                            .to(LOG_ROUTE_PREFIX + "notification.failed").to(getMailOutputUri(true)).end();
                }

                // Notification route for successful proceed messages
                if ("".equals(Configuration.get(ConfigurationKey.MailNotificationSuccessRecipient))) {
                    from("direct:success").to("log:fooSuccess").end();
                } else {
                    from("direct:success").routeId("mail-notification-on-success")
                            .filter(constant(Configuration.get(ConfigurationKey.MailNotificationSuccessRecipient))
                                    .isNotEqualTo(""))
                            .process(new PrepareNotificationMailProcessor())
                            .to(LOG_ROUTE_PREFIX + "notification.success").to(getMailOutputUri(false)).end();
                }

            }
        };

    }

    private static String getMailInputUri() {
        return Configuration.get(ConfigurationKey.MailReceiveType) + "://"
                + Configuration.get(ConfigurationKey.MailReceiveUsername) + "@"
                + Configuration.get(ConfigurationKey.MailReceiveHostname) + "?password="
                + Configuration.get(ConfigurationKey.MailReceivePassword) + "&consumer.delay="
                + Configuration.get(ConfigurationKey.MailReceiveInterval) + "&delete="
                + Configuration.get(ConfigurationKey.MailReceiveDeleteMail)
                + Configuration.get(ConfigurationKey.MailReceiveOptions);
    }

    private static String getMailOutputUri(final boolean failed) {

        String to = failed ? Configuration.get(ConfigurationKey.MailNotificationFailedRecipient)
                : Configuration.get(ConfigurationKey.MailNotificationSuccessRecipient);

        return Configuration.get(ConfigurationKey.MailSMTPType) + "://"
                + Configuration.get(ConfigurationKey.MailSMTPUsername) + "@"
                + Configuration.get(ConfigurationKey.MailSMTPHostname) + "?password="
                + Configuration.get(ConfigurationKey.MailSMTPPassword) + "&from="
                + Configuration.get(ConfigurationKey.MailNotificationSender) + "&to=" + to;
    }

    //    private static String getWebDAVUri(final CamelContext context) {
    //        return "jetty:"
    //                       + Configuration.get(ConfigurationKey.TargetWebDAVUrl)
    //                       + "?bridgeEndpoint=false"
    //                       + "&chunked=false"
    //                       + "&throwExceptionOnFailure=true"
    //                       + "&disableStreamCache=false"
    //                       + Configuration.get(ConfigurationKey.TargetWebDAVOptions);
    //    }
    private static String getWebDAVUri(final CamelContext context) {
        try {
            URL url = new URL(Configuration.get(ConfigurationKey.TargetWebDAVUrl));
            String hostname = url.getHost();
            int port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();

            return "http4:" + hostname + ":" + port + "?bridgeEndpoint=false" + "&throwExceptionOnFailure=true"
                    + "&disableStreamCache=false" + Configuration.get(ConfigurationKey.TargetWebDAVOptions);
        } catch (MalformedURLException ex) {
            throw new IllegalArgumentException(ex);
        }
    }

    private static String getFileSystemUri() {
        return "file://" + Configuration.get(ConfigurationKey.TargetFileSystemPath) + "?fileExist=Fail"
                + Configuration.get(ConfigurationKey.TargetFileSystemOptions);
    }

    /**
     * Returns URI of SMB component.
     * <p>
     * URI format = smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]]]][?options]
     * <p>
     * Options:
     * <ul>
     * <li>password: <b>Mandatory</b> Specifies the password to use to log in to the remote file system.</li>
     * <li> localWorkDirectory: When consuming, a local work directory can be used to store the remote
     * file content directly in local files, to avoid loading the content into memory.
     * This is beneficial, if you consume a very big remote file and thus can conserve
     * memory. See below for more details.</li>
     * </ul>
     *
     * @return
     */
    private static String getSmbUri() {
        StringBuilder sb = new StringBuilder("smb://");
        if (StringUtils.hasText(Configuration.get(ConfigurationKey.TargetSmbDomain))) {
            sb.append(Configuration.get(ConfigurationKey.TargetSmbDomain));
            sb.append(";");
        }

        sb.append(Configuration.get(ConfigurationKey.TargetSmbUsername));

        sb.append("@");

        sb.append(Configuration.get(ConfigurationKey.TargetSmbHostname));

        sb.append("/");

        if (StringUtils.hasText(Configuration.get(ConfigurationKey.TargetSmbShare))) {
            sb.append(Configuration.get(ConfigurationKey.TargetSmbShare));
        }

        sb.append("?localWorkDirectory=");
        sb.append(System.getProperty("java.io.tmpdir"));

        if (StringUtils.hasText(Configuration.get(ConfigurationKey.TargetSmbPassword))) {
            sb.append("&password=");
            sb.append(Configuration.get(ConfigurationKey.TargetSmbPassword));
        }

        return sb.toString();
    }

    private static String getGoogleDriveUploadFileUri(final CamelContext context) {

        GoogleDriveConfiguration configuration = new GoogleDriveConfiguration();
        // accessToken OAuth 2 access token. This typically expires after an hour so refreshToken is recommended for long term usage.
        //configuration.setAccessToken("accessToken");
        configuration.setApplicationName("MailAttachmentGateway");
        configuration.setScopes(Arrays.asList(DriveScopes.DRIVE_FILE));

        GoogleDriveComponent googleDriveComponent = new GoogleDriveComponent();
        googleDriveComponent.setConfiguration(configuration);
        googleDriveComponent.setClientFactory(new BatchGoogleDriveClientFactory());
        context.addComponent("google-drive", googleDriveComponent);

        String PATH_PREFIX = GoogleDriveApiCollection.getCollection().getApiName(DriveFilesApiMethod.class)
                .getName();

        return "google-drive://" + PATH_PREFIX + "/insert";
    }

}