Java tutorial
/* * 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"; } }