git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube...
authorvasary.daniel <TFS\vasary.daniel>
Fri, 4 Mar 2022 15:19:24 +0000 (15:19 +0000)
committervasary.daniel <TFS\vasary.daniel>
Fri, 4 Mar 2022 15:19:24 +0000 (15:19 +0000)
14 files changed:
server/user.jobengine.log4j/.classpath [new file with mode: 0644]
server/user.jobengine.log4j/.project [new file with mode: 0644]
server/user.jobengine.log4j/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
server/user.jobengine.log4j/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
server/user.jobengine.log4j/META-INF/MANIFEST.MF [new file with mode: 0644]
server/user.jobengine.log4j/build.properties [new file with mode: 0644]
server/user.jobengine.log4j/lib/log4j-api-2.17.2.jar [new file with mode: 0644]
server/user.jobengine.log4j/lib/log4j-core-2.17.2.jar [new file with mode: 0644]
server/user.jobengine.log4j/lib/log4j-slf4j-impl-2.17.2.jar [new file with mode: 0644]
server/user.jobengine.log4j/src/user/commons/log4j2/appender/HTMLMailAppender.java [new file with mode: 0644]
server/user.jobengine.log4j/src/user/commons/log4j2/appender/SmtpManager.java [new file with mode: 0644]
server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeFinishMarker.java [new file with mode: 0644]
server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeMarker.java [new file with mode: 0644]
server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeUndoMarker.java [new file with mode: 0644]

diff --git a/server/user.jobengine.log4j/.classpath b/server/user.jobengine.log4j/.classpath
new file mode 100644 (file)
index 0000000..4d79cc5
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry exported="true" kind="lib" path="lib/log4j-slf4j-impl-2.17.2.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/log4j-api-2.17.2.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/log4j-core-2.17.2.jar"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/server/user.jobengine.log4j/.project b/server/user.jobengine.log4j/.project
new file mode 100644 (file)
index 0000000..d074e0e
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>user.jobengine.log4j</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/server/user.jobengine.log4j/.settings/org.eclipse.jdt.core.prefs b/server/user.jobengine.log4j/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..e2860e9
--- /dev/null
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.release=disabled\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/server/user.jobengine.log4j/.settings/org.eclipse.pde.core.prefs b/server/user.jobengine.log4j/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..b7e72d0
--- /dev/null
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1\r
+pluginProject.extensions=false\r
+resolve.requirebundle=false\r
diff --git a/server/user.jobengine.log4j/META-INF/MANIFEST.MF b/server/user.jobengine.log4j/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..e9bb79b
--- /dev/null
@@ -0,0 +1,78 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Log4j
+Bundle-SymbolicName: user.jobengine.log4j
+Bundle-Version: 1.0.0.qualifier
+Automatic-Module-Name: user.jobengine.log4j
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ClassPath: .,
+ lib/log4j-api-2.17.2.jar,
+ lib/log4j-core-2.17.2.jar,
+ lib/log4j-slf4j-impl-2.17.2.jar
+Export-Package: org.apache.logging.log4j,
+ org.apache.logging.log4j.core,
+ org.apache.logging.log4j.core.appender,
+ org.apache.logging.log4j.core.appender.db,
+ org.apache.logging.log4j.core.appender.db.jdbc,
+ org.apache.logging.log4j.core.appender.mom,
+ org.apache.logging.log4j.core.appender.mom.jeromq,
+ org.apache.logging.log4j.core.appender.mom.kafka,
+ org.apache.logging.log4j.core.appender.nosql,
+ org.apache.logging.log4j.core.appender.rewrite,
+ org.apache.logging.log4j.core.appender.rolling,
+ org.apache.logging.log4j.core.appender.rolling.action,
+ org.apache.logging.log4j.core.appender.routing,
+ org.apache.logging.log4j.core.async,
+ org.apache.logging.log4j.core.config,
+ org.apache.logging.log4j.core.config.arbiters,
+ org.apache.logging.log4j.core.config.builder.api,
+ org.apache.logging.log4j.core.config.builder.impl,
+ org.apache.logging.log4j.core.config.composite,
+ org.apache.logging.log4j.core.config.json,
+ org.apache.logging.log4j.core.config.plugins,
+ org.apache.logging.log4j.core.config.plugins.convert,
+ org.apache.logging.log4j.core.config.plugins.processor,
+ org.apache.logging.log4j.core.config.plugins.util,
+ org.apache.logging.log4j.core.config.plugins.validation,
+ org.apache.logging.log4j.core.config.plugins.validation.constraints,
+ org.apache.logging.log4j.core.config.plugins.validation.validators,
+ org.apache.logging.log4j.core.config.plugins.visitors,
+ org.apache.logging.log4j.core.config.properties,
+ org.apache.logging.log4j.core.config.status,
+ org.apache.logging.log4j.core.config.xml,
+ org.apache.logging.log4j.core.config.yaml,
+ org.apache.logging.log4j.core.filter,
+ org.apache.logging.log4j.core.impl,
+ org.apache.logging.log4j.core.jackson,
+ org.apache.logging.log4j.core.jmx,
+ org.apache.logging.log4j.core.layout,
+ org.apache.logging.log4j.core.layout.internal,
+ org.apache.logging.log4j.core.lookup,
+ org.apache.logging.log4j.core.message,
+ org.apache.logging.log4j.core.net,
+ org.apache.logging.log4j.core.net.ssl,
+ org.apache.logging.log4j.core.osgi,
+ org.apache.logging.log4j.core.parser,
+ org.apache.logging.log4j.core.pattern,
+ org.apache.logging.log4j.core.script,
+ org.apache.logging.log4j.core.selector,
+ org.apache.logging.log4j.core.time,
+ org.apache.logging.log4j.core.time.internal,
+ org.apache.logging.log4j.core.tools,
+ org.apache.logging.log4j.core.tools.picocli,
+ org.apache.logging.log4j.core.util,
+ org.apache.logging.log4j.core.util.datetime,
+ org.apache.logging.log4j.internal,
+ org.apache.logging.log4j.message,
+ org.apache.logging.log4j.simple,
+ org.apache.logging.log4j.spi,
+ org.apache.logging.log4j.status,
+ org.apache.logging.log4j.util,
+ org.apache.logging.slf4j,
+ org.slf4j.impl,
+ user.commons.log4j2.appender,
+ user.commons.log4j2.marker
+Import-Package: javax.mail;version="1.5.0",
+ javax.mail.internet;version="1.5.0",
+ javax.mail.util;version="1.5.0"
+Require-Bundle: org.eclipse.osgi;bundle-version="3.11.2"
diff --git a/server/user.jobengine.log4j/build.properties b/server/user.jobengine.log4j/build.properties
new file mode 100644 (file)
index 0000000..4a34f79
--- /dev/null
@@ -0,0 +1,7 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               lib/log4j-api-2.17.2.jar,\\r
+               lib/log4j-core-2.17.2.jar,\\r
+               lib/log4j-slf4j-impl-2.17.2.jar\r
diff --git a/server/user.jobengine.log4j/lib/log4j-api-2.17.2.jar b/server/user.jobengine.log4j/lib/log4j-api-2.17.2.jar
new file mode 100644 (file)
index 0000000..16d9061
Binary files /dev/null and b/server/user.jobengine.log4j/lib/log4j-api-2.17.2.jar differ
diff --git a/server/user.jobengine.log4j/lib/log4j-core-2.17.2.jar b/server/user.jobengine.log4j/lib/log4j-core-2.17.2.jar
new file mode 100644 (file)
index 0000000..0fd0051
Binary files /dev/null and b/server/user.jobengine.log4j/lib/log4j-core-2.17.2.jar differ
diff --git a/server/user.jobengine.log4j/lib/log4j-slf4j-impl-2.17.2.jar b/server/user.jobengine.log4j/lib/log4j-slf4j-impl-2.17.2.jar
new file mode 100644 (file)
index 0000000..a5cc396
Binary files /dev/null and b/server/user.jobengine.log4j/lib/log4j-slf4j-impl-2.17.2.jar differ
diff --git a/server/user.jobengine.log4j/src/user/commons/log4j2/appender/HTMLMailAppender.java b/server/user.jobengine.log4j/src/user/commons/log4j2/appender/HTMLMailAppender.java
new file mode 100644 (file)
index 0000000..e957186
--- /dev/null
@@ -0,0 +1,163 @@
+package user.commons.log4j2.appender;
+
+import java.io.Serializable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.ValidPort;
+import org.apache.logging.log4j.core.filter.ThresholdFilter;
+import org.apache.logging.log4j.core.layout.HtmlLayout;
+import org.apache.logging.log4j.core.util.Booleans;
+
+/**
+ * Send an e-mail when a specific logging event occurs, typically on errors or fatal errors.
+ *
+ * <p>
+ * The number of logging events delivered in this e-mail depend on the value of <b>BufferSize</b> option. The <code>SmtpAppender</code> keeps only the last
+ * <code>BufferSize</code> logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application
+ * context.
+ *
+ * By default, an email message will formatted as HTML. This can be modified by setting a layout for the appender.
+ *
+ * By default, an email message will be sent when an ERROR or higher severity message is appended. This can be modified by setting a filter for the appender.
+ */
+@Plugin(name = "HTMLMailAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
+public final class HTMLMailAppender extends AbstractAppender {
+
+       private static final int DEFAULT_BUFFER_SIZE = 512;
+
+       private static final int CONCURRENT_MAIL_QUEUES = 1;
+       private static final ExecutorService executor = Executors.newFixedThreadPool(CONCURRENT_MAIL_QUEUES);
+
+       /**
+        * Create a SmtpAppender.
+        *
+        * @param name
+        *            The name of the Appender.
+        * @param to
+        *            The comma-separated list of recipient email addresses.
+        * @param cc
+        *            The comma-separated list of CC email addresses.
+        * @param bcc
+        *            The comma-separated list of BCC email addresses.
+        * @param from
+        *            The email address of the sender.
+        * @param replyTo
+        *            The comma-separated list of reply-to email addresses.
+        * @param subject
+        *            The subject of the email message.
+        * @param smtpProtocol
+        *            The SMTP transport protocol (such as "smtps", defaults to "smtp").
+        * @param smtpHost
+        *            The SMTP hostname to send to.
+        * @param smtpPortStr
+        *            The SMTP port to send to.
+        * @param smtpUsername
+        *            The username required to authenticate against the SMTP server.
+        * @param smtpPassword
+        *            The password required to authenticate against the SMTP server.
+        * @param smtpDebug
+        *            Enable mail session debuging on STDOUT.
+        * @param bufferSizeStr
+        *            How many log events should be buffered for inclusion in the message?
+        * @param layout
+        *            The layout to use (defaults to HtmlLayout).
+        * @param filter
+        *            The Filter or null (defaults to ThresholdFilter, level of ERROR).
+        * @param ignore
+        *            If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they are propagated to the caller.
+        * @return The SmtpAppender.
+        */
+       @PluginFactory
+       public static HTMLMailAppender createAppender(@PluginConfiguration final Configuration config, @PluginAttribute("name") @Required final String name,
+                       @PluginAttribute("to") final String to, @PluginAttribute("cc") final String cc, @PluginAttribute("bcc") final String bcc,
+                       @PluginAttribute("from") final String from, @PluginAttribute("replyTo") final String replyTo, @PluginAttribute("subject") final String subject,
+                       @PluginAttribute("smtpProtocol") final String smtpProtocol, @PluginAttribute("smtpHost") final String smtpHost,
+                       @PluginAttribute(value = "smtpPort", defaultString = "0") @ValidPort final String smtpPortStr,
+                       @PluginAttribute("smtpUsername") final String smtpUsername, @PluginAttribute(value = "smtpPassword", sensitive = true) final String smtpPassword,
+                       @PluginAttribute("smtpDebug") final String smtpDebug, @PluginAttribute("bufferSize") final String bufferSizeStr,
+                       @PluginElement("Layout") Layout<? extends Serializable> layout, @PluginElement("Filter") Filter filter,
+                       @PluginAttribute("ignoreExceptions") final String ignore) {
+               if (name == null) {
+                       LOGGER.error("No name provided for SmtpAppender");
+                       return null;
+               }
+
+               final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
+               final int smtpPort = AbstractAppender.parseInt(smtpPortStr, 0);
+               final boolean isSmtpDebug = Boolean.parseBoolean(smtpDebug);
+               final int bufferSize = bufferSizeStr == null ? DEFAULT_BUFFER_SIZE : Integer.parseInt(bufferSizeStr);
+
+               if (layout == null) {
+                       layout = HtmlLayout.createDefaultLayout();
+               }
+               if (filter == null) {
+                       filter = ThresholdFilter.createFilter(null, null, null);
+               }
+               final Configuration configuration = config != null ? config : new DefaultConfiguration();
+
+               final SmtpManager manager = SmtpManager.getSmtpManager(configuration, to, cc, bcc, from, replyTo, subject, smtpProtocol, smtpHost, smtpPort,
+                               smtpUsername, smtpPassword, isSmtpDebug, filter.toString(), bufferSize);
+               if (manager == null)
+                       return null;
+
+               return new HTMLMailAppender(name, filter, layout, manager, ignoreExceptions);
+       }
+
+       /** The SMTP Manager */
+       private final SmtpManager manager;
+
+       private HTMLMailAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final SmtpManager manager,
+                       final boolean ignoreExceptions) {
+               super(name, filter, layout, ignoreExceptions);
+               this.manager = manager;
+       }
+
+       /**
+        * Perform SmtpAppender specific appending actions, mainly adding the event to a cyclic buffer and checking if the event triggers an e-mail to be sent.
+        *
+        * @param event
+        *            The Log event.
+        */
+       @Override
+       public void append(final LogEvent event) {
+               //System.out.println("append " + event.getMessage().getFormattedMessage());
+               final LogEvent eventToSend = event.toImmutable();
+               executor.submit(() -> {
+                       manager.sendEvents(getLayout(), eventToSend);
+               });
+
+       }
+
+       /**
+        * Capture all events in CyclicBuffer.
+        *
+        * @param event
+        *            The Log event.
+        * @return true if the event should be filtered.
+        */
+       @Override
+       public boolean isFiltered(final LogEvent event) {
+               final boolean filtered = super.isFiltered(event);
+               //              if (filtered) {
+               //                      manager.add(event);
+               //              }
+
+               //System.out.println("isFiltered");
+               return filtered;
+       }
+}
diff --git a/server/user.jobengine.log4j/src/user/commons/log4j2/appender/SmtpManager.java b/server/user.jobengine.log4j/src/user/commons/log4j2/appender/SmtpManager.java
new file mode 100644 (file)
index 0000000..72d87be
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 user.commons.log4j2.appender;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.activation.CommandMap;
+import javax.activation.DataSource;
+import javax.activation.MailcapCommandMap;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractManager;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.layout.AbstractStringLayout.Serializer;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.net.MimeMessageBuilder;
+import org.apache.logging.log4j.core.util.NameUtil;
+import org.apache.logging.log4j.core.util.NetUtils;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.Strings;
+
+import user.commons.log4j2.marker.MediaCubeFinishMarker;
+import user.commons.log4j2.marker.MediaCubeMarker;
+import user.commons.log4j2.marker.MediaCubeUndoMarker;
+
+/**
+ * Manager for sending SMTP events.
+ */
+public class SmtpManager extends AbstractManager {
+       /**
+        * Factory data.
+        */
+       private static class FactoryData {
+               private final String to;
+               private final String cc;
+               private final String bcc;
+               private final String from;
+               private final String replyto;
+               private final Serializer subject;
+               private final String protocol;
+               private final String host;
+               private final int port;
+               private final String username;
+               private final String password;
+               private final boolean isDebug;
+               private final int numElements;
+
+               public FactoryData(final String to, final String cc, final String bcc, final String from, final String replyTo,
+                               final Serializer subjectSerializer, final String protocol, final String host, final int port,
+                               final String username, final String password, final boolean isDebug, final int numElements) {
+                       this.to = to;
+                       this.cc = cc;
+                       this.bcc = bcc;
+                       this.from = from;
+                       this.replyto = replyTo;
+                       this.subject = subjectSerializer;
+                       this.protocol = protocol;
+                       this.host = host;
+                       this.port = port;
+                       this.username = username;
+                       this.password = password;
+                       this.isDebug = isDebug;
+                       this.numElements = numElements;
+               }
+       }
+
+       /**
+        * Factory to create the SMTP Manager.
+        */
+       private static class SMTPManagerFactory implements ManagerFactory<SmtpManager, FactoryData> {
+
+               private Authenticator buildAuthenticator(final String username, final String password) {
+                       if (null != password && null != username) {
+                               return new Authenticator() {
+                                       private final PasswordAuthentication passwordAuthentication = new PasswordAuthentication(username,
+                                                       password);
+
+                                       @Override
+                                       protected PasswordAuthentication getPasswordAuthentication() {
+                                               return passwordAuthentication;
+                                       }
+                               };
+                       }
+                       return null;
+               }
+
+               @Override
+               public SmtpManager createManager(final String name, final FactoryData data) {
+                       final String prefix = "mail." + data.protocol;
+
+                       final Properties properties = PropertiesUtil.getSystemProperties();
+                       properties.put("mail.transport.protocol", data.protocol);
+                       if (properties.getProperty("mail.host") == null) {
+                               // Prevent an UnknownHostException in Java 7
+                               properties.put("mail.host", NetUtils.getLocalHostname());
+                       }
+
+                       if (null != data.host) {
+                               properties.put(prefix + ".host", data.host);
+                       }
+                       if (data.port > 0) {
+                               properties.put(prefix + ".port", String.valueOf(data.port));
+                       }
+
+                       final Authenticator authenticator = buildAuthenticator(data.username, data.password);
+                       if (null != authenticator) {
+                               properties.put(prefix + ".auth", "true");
+                       }
+
+                       final Session session = Session.getInstance(properties, authenticator);
+                       session.setProtocolForAddress("rfc822", data.protocol);
+                       session.setDebug(data.isDebug);
+                       return new SmtpManager(name, session, null, data);
+               }
+       }
+
+       private static final SMTPManagerFactory FACTORY = new SMTPManagerFactory();
+       private static Map<String, List<LogEvent>> sessionEvents = new ConcurrentHashMap<>();
+
+       private static MimeMessage createMimeMessage(final FactoryData data, final Session session,
+                       final LogEvent appendEvent) throws MessagingException {
+               return new MimeMessageBuilder(session).setFrom(data.from).setReplyTo(data.replyto)
+                               .setRecipients(Message.RecipientType.TO, data.to).setRecipients(Message.RecipientType.CC, data.cc)
+                               .setRecipients(Message.RecipientType.BCC, data.bcc).setSubject(data.subject.toSerializable(appendEvent))
+                               .build();
+       }
+
+       public static SmtpManager getSmtpManager(final Configuration config, final String to, final String cc,
+                       final String bcc, final String from, final String replyTo, final String subject, String protocol,
+                       final String host, final int port, final String username, final String password, final boolean isDebug,
+                       final String filterName, final int numElements) {
+               if (Strings.isEmpty(protocol)) {
+                       protocol = "smtp";
+               }
+
+               final StringBuilder sb = new StringBuilder();
+               if (to != null) {
+                       sb.append(to);
+               }
+               sb.append(':');
+               if (cc != null) {
+                       sb.append(cc);
+               }
+               sb.append(':');
+               if (bcc != null) {
+                       sb.append(bcc);
+               }
+               sb.append(':');
+               if (from != null) {
+                       sb.append(from);
+               }
+               sb.append(':');
+               if (replyTo != null) {
+                       sb.append(replyTo);
+               }
+               sb.append(':');
+               if (subject != null) {
+                       sb.append(subject);
+               }
+               sb.append(':');
+               sb.append(protocol).append(':').append(host).append(':').append("port").append(':');
+               if (username != null) {
+                       sb.append(username);
+               }
+               sb.append(':');
+               if (password != null) {
+                       sb.append(password);
+               }
+               sb.append(isDebug ? ":debug:" : "::");
+               sb.append(filterName);
+
+               final String name = "SMTP:" + NameUtil.md5(sb.toString());
+               final Serializer subjectSerializer = PatternLayout.newSerializerBuilder().setConfiguration(config)
+                               .setPattern(subject).build();
+
+               return getManager(name, FACTORY, new FactoryData(to, cc, bcc, from, replyTo, subjectSerializer, protocol, host,
+                               port, username, password, isDebug, numElements));
+       }
+
+       private final Session session;
+       private volatile MimeMessage message;
+       private final FactoryData data;
+       private String defaultRecipient;
+       private String defaultSubject;
+
+       protected SmtpManager(final String name, final Session session, final MimeMessage message, final FactoryData data) {
+               super(null, name);
+               this.session = session;
+               this.message = message;
+               this.data = data;
+               this.defaultRecipient = data.to;
+       }
+
+       // public void add(LogEvent event) {
+       // if (event instanceof Log4jLogEvent && event.getMessage() instanceof
+       // ReusableMessage) {
+       // ((Log4jLogEvent) event).makeMessageImmutable();
+       // } else if (event instanceof MutableLogEvent) {
+       // event = ((MutableLogEvent) event).createMemento();
+       // }
+       // }
+
+       private synchronized void connect(final LogEvent appendEvent) {
+               if (message != null) {
+                       return;
+               }
+               try {
+                       message = createMimeMessage(data, session, appendEvent);
+                       this.defaultSubject = message.getSubject();
+               } catch (final MessagingException e) {
+                       logError("Could not set SmtpAppender message options", e);
+                       message = null;
+               }
+       }
+
+       protected void encodeContent(final byte[] bytes, final String encoding, final ByteArrayOutputStream out)
+                       throws MessagingException, IOException {
+               try (final OutputStream encoder = MimeUtility.encode(out, encoding)) {
+                       encoder.write(bytes);
+               }
+       }
+
+       protected byte[] encodeContentToBytes(final byte[] rawBytes, final String encoding)
+                       throws MessagingException, IOException {
+               final ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+               encodeContent(rawBytes, encoding, encoded);
+               return encoded.toByteArray();
+       }
+
+       protected byte[] formatContentToBytes(final List<LogEvent> events, final Layout<?> layout) throws IOException {
+               final ByteArrayOutputStream raw = new ByteArrayOutputStream();
+               writeContent(events, layout, raw);
+               return raw.toByteArray();
+       }
+
+       protected String getEncoding(final byte[] rawBytes, final String contentType) {
+               final DataSource dataSource = new ByteArrayDataSource(rawBytes, contentType);
+               return MimeUtility.getEncoding(dataSource);
+       }
+
+       protected InternetHeaders getHeaders(final String contentType, final String encoding) {
+               final InternetHeaders headers = new InternetHeaders();
+               headers.setHeader("Content-Type", contentType + "; charset=UTF-8");
+               headers.setHeader("Content-Transfer-Encoding", encoding);
+               return headers;
+       }
+
+       private Level getLowestLevel(final Level level, final List<LogEvent> events) {
+               Level mailLevel = level;
+               if (events != null) {
+                       for (LogEvent event : events) {
+                               if (event.getLevel().intLevel() < mailLevel.intLevel())
+                                       mailLevel = event.getLevel();
+                       }
+               }
+               return mailLevel;
+       }
+
+       protected MimeMultipart getMimeMultipart(final byte[] encodedBytes, final InternetHeaders headers)
+                       throws MessagingException {
+               final MimeMultipart mp = new MimeMultipart();
+               final MimeBodyPart part = new MimeBodyPart(headers, encodedBytes);
+               mp.addBodyPart(part);
+               return mp;
+       }
+
+       private void sendEmail(final String to, final String subject, byte[] content, String contentType) {
+               try {
+                       MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
+                       mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
+                       mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
+                       mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
+                       mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
+                       mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822");
+                       message.setSubject(subject);
+                       message.setRecipients(RecipientType.TO, to);
+                       final String encoding = getEncoding(content, contentType);
+                       final byte[] encodedBytes = encodeContentToBytes(content, encoding);
+                       final InternetHeaders headers = getHeaders(contentType, encoding);
+                       final MimeMultipart mp = getMimeMultipart(encodedBytes, headers);
+                       sendMultipartMessage(message, mp);
+               } catch (final MessagingException | IOException | RuntimeException e) {
+                       logError("Caught exception while sending e-mail notification.", e);
+                       throw new LoggingException("Error occurred while sending email", e);
+               }
+       }
+
+       /**
+        * Send the contents of the cyclic buffer as an e-mail message.
+        *
+        * @param layout      The layout for formatting the events.
+        * @param appendEvent The event that triggered the send.
+        */
+       public void sendEvents(final Layout<?> layout, final LogEvent appendEvent) {
+               if (message == null)
+                       connect(appendEvent);
+
+               // System.out.println(appendEvent.getMarker().getClass().getSimpleName() + " " +
+               // new String(layout.toByteArray(appendEvent)));
+               String to = defaultRecipient;
+               String subject = defaultSubject;
+               if (appendEvent.getMarker() instanceof MediaCubeFinishMarker) {
+                       MediaCubeFinishMarker mcm = (MediaCubeFinishMarker) appendEvent.getMarker();
+                       storeSessionEvent(mcm, appendEvent);
+                       String sessionID = mcm.getSessionID();
+                       if (sessionID == null)
+                               return;
+
+                       List<LogEvent> events = sessionEvents.get(sessionID);
+
+                       // ha error, akkor mindenkepp elmegy
+                       if (mcm.isUseSessionLog() || getLowestLevel(Level.INFO, events).intLevel() < Level.WARN.intLevel()) {
+                               sendSessionEvents(events, mcm, layout, appendEvent.getLevel());
+                       }
+
+               }
+
+               if (appendEvent.getMarker() instanceof MediaCubeUndoMarker) {
+                       undoSessionEvents((MediaCubeMarker) appendEvent.getMarker());
+                       return;
+               }
+
+               if (appendEvent.getMarker() instanceof MediaCubeMarker) {
+                       MediaCubeMarker mcm = (MediaCubeMarker) appendEvent.getMarker();
+                       if (mcm.getSessionID() == null) {
+                               if (mcm.getTo() != null)
+                                       to = mcm.getTo();
+                               if (mcm.getSubject() != null)
+                                       subject = mcm.getSubject();
+                       } else {
+                               storeSessionEvent(mcm, appendEvent);
+                               return;
+                       }
+
+               }
+
+               sendEvents(to, subject, layout, Arrays.asList(appendEvent));
+       }
+
+       private void sendEvents(final String to, final String subject, final Layout<?> layout,
+                       final List<LogEvent> events) {
+               try {
+                       final byte[] rawBytes = formatContentToBytes(events, layout);
+                       // final String contentType = layout.getContentType();
+
+                       sendEmail(to, subject, rawBytes, "text/html; charset=utf-8");
+               } catch (Exception e) {
+                       logError("Caught exception while sending e-mail notification.", e);
+                       throw new LoggingException("Error occurred while sending email", e);
+               }
+       }
+
+       protected void sendMultipartMessage(final MimeMessage msg, final MimeMultipart mp) throws MessagingException {
+               synchronized (msg) {
+                       msg.setContent(mp);
+                       msg.setSentDate(new Date());
+                       Transport.send(msg);
+               }
+       }
+
+       private void sendSessionEvents(final List<LogEvent> events, final MediaCubeMarker mcm, final Layout<?> layout,
+                       final Level level) {
+               String sessionID = mcm.getSessionID();
+               if (events == null)
+                       return;
+
+               Level mailLevel = getLowestLevel(level, events);
+
+               String to = mcm.getTo() == null ? defaultRecipient : defaultRecipient + "," + mcm.getTo();
+               String subject = mcm.getSessionName() == null ? defaultSubject
+                               : String.format("%s: %s #%s", mailLevel, mcm.getSessionName(), sessionID);
+               sendEvents(to, subject, layout, events);
+               sessionEvents.remove(sessionID);
+       }
+
+       private void storeSessionEvent(MediaCubeMarker mcm, LogEvent appendEvent) {
+               String sessionID = mcm.getSessionID();
+               List<LogEvent> events = sessionEvents.get(sessionID);
+               if (events == null) {
+                       events = new ArrayList<>();
+                       sessionEvents.put(sessionID, events);
+               }
+               events.add(appendEvent);
+       }
+
+       private void undoSessionEvents(final MediaCubeMarker mcm) {
+               String sessionID = mcm.getSessionID();
+               if (sessionID != null && sessionEvents.containsKey(sessionID))
+                       sessionEvents.remove(sessionID);
+       }
+
+       protected void writeBuffer(List<LogEvent> events, final Layout<?> layout, final OutputStream out)
+                       throws IOException {
+               out.write("<html>".getBytes());
+               out.write("<body>".getBytes());
+
+               out.write("<table>".getBytes());
+               for (final LogEvent priorEvent : events) {
+                       out.write("<tr><td>".getBytes());
+                       final byte[] bytes = layout.toByteArray(priorEvent);
+                       out.write(bytes);
+                       out.write("</td></tr>".getBytes());
+               }
+               out.write("</table>".getBytes());
+               out.write("</body>".getBytes());
+               out.write("</html>".getBytes());
+       }
+
+       private void writeContent(final List<LogEvent> events, final Layout<?> layout, final ByteArrayOutputStream out)
+                       throws IOException {
+               writeHeader(layout, out);
+               writeBuffer(events, layout, out);
+               writeFooter(layout, out);
+       }
+
+       protected void writeFooter(final Layout<?> layout, final OutputStream out) throws IOException {
+               final byte[] footer = layout.getFooter();
+               if (footer != null) {
+                       out.write(footer);
+               }
+       }
+
+       protected void writeHeader(final Layout<?> layout, final OutputStream out) throws IOException {
+               final byte[] header = layout.getHeader();
+               if (header != null) {
+                       out.write(header);
+               }
+       }
+}
diff --git a/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeFinishMarker.java b/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeFinishMarker.java
new file mode 100644 (file)
index 0000000..2f6170c
--- /dev/null
@@ -0,0 +1,20 @@
+package user.commons.log4j2.marker;\r
+\r
+@SuppressWarnings("serial")\r
+public class MediaCubeFinishMarker extends MediaCubeMarker {\r
+\r
+       public MediaCubeFinishMarker(MediaCubeMarker parent) {\r
+               setSessionID(parent.getSessionID());\r
+               setSessionName(parent.getSessionName());\r
+               setTo(parent.getTo());\r
+               setUseSessionLog(parent.isUseSessionLog());\r
+               setParents(parent);\r
+       }\r
+\r
+       public MediaCubeFinishMarker(MediaCubeMarker parent, String to) {\r
+               super(to);\r
+               setSessionID(parent.getSessionID());\r
+               setSessionName(parent.getSessionName());\r
+               setParents(parent);\r
+       }\r
+}\r
diff --git a/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeMarker.java b/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeMarker.java
new file mode 100644 (file)
index 0000000..2f4e618
--- /dev/null
@@ -0,0 +1,78 @@
+package user.commons.log4j2.marker;\r
+\r
+import org.apache.logging.log4j.MarkerManager.Log4jMarker;\r
+\r
+@SuppressWarnings("serial")\r
+public class MediaCubeMarker extends Log4jMarker {\r
+       private static final String MEDIACUBE = "MEDIACUBE";\r
+       private String to;\r
+       private String subject;\r
+       private String sessionID;\r
+       private String sessionName;\r
+       private boolean useSessionLog;\r
+\r
+       public MediaCubeMarker() {\r
+               super(MEDIACUBE);\r
+       }\r
+\r
+       public MediaCubeMarker(String to) {\r
+               super(MEDIACUBE);\r
+               this.to = to;\r
+       }\r
+\r
+       public MediaCubeMarker(String to, String subject) {\r
+               super(MEDIACUBE);\r
+               this.to = to;\r
+               this.subject = subject;\r
+       }\r
+\r
+       public String getSessionID() {\r
+               return sessionID;\r
+       }\r
+\r
+       public String getSessionName() {\r
+               return sessionName;\r
+       }\r
+\r
+       public String getSubject() {\r
+               return subject;\r
+       }\r
+\r
+       public String getTo() {\r
+               return to;\r
+       }\r
+\r
+       public boolean isUseSessionLog() {\r
+               return useSessionLog;\r
+       }\r
+\r
+       public void setSessionID(String sessionID) {\r
+               this.sessionID = sessionID;\r
+       }\r
+\r
+       public void setSessionName(String sessionName) {\r
+               this.sessionName = sessionName;\r
+       }\r
+\r
+       public void setSubject(String subject) {\r
+               this.subject = subject;\r
+       }\r
+\r
+       public void setTo(String to) {\r
+               this.to = to;\r
+       }\r
+\r
+       public void setUseSessionLog(boolean useSessionLog) {\r
+               this.useSessionLog = useSessionLog;\r
+       }\r
+\r
+       //      @Override\r
+       //      public boolean equals(Object o) {\r
+       //              if (o == null || !o.getClass().equals(MediaCubeMarker.class))\r
+       //                      return false;\r
+       //\r
+       //\r
+       //              return true;\r
+       //      }\r
+\r
+}\r
diff --git a/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeUndoMarker.java b/server/user.jobengine.log4j/src/user/commons/log4j2/marker/MediaCubeUndoMarker.java
new file mode 100644 (file)
index 0000000..2b2ffbd
--- /dev/null
@@ -0,0 +1,8 @@
+package user.commons.log4j2.marker;\r
+\r
+@SuppressWarnings("serial")\r
+public class MediaCubeUndoMarker extends MediaCubeMarker {\r
+       public MediaCubeUndoMarker(String sessionID) {\r
+               setSessionID(sessionID);\r
+       }\r
+}\r