Skip to content

Commit

Permalink
Added PID file creation; Updated README; Done some code cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
domax committed Jun 14, 2017
1 parent 57dea8f commit 42372e5
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 77 deletions.
59 changes: 48 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,37 @@ These dedicated folders are designed to keep the intermediate data files that
are in fact the patches or bundles of Git or other VCS system.
This bridge is duplex - so that you can exchange data in both directions.

Contents
--------

1. [The Short Explanation](#the-short-explanation)
2. [How It Works In A Nutshell](#how-it-works-in-a-nutshell)
1. [The Overall Diagram](#the-overall-diagram)
3. [Build And Run](#build-and-run)
1. [Prerequisites](#prerequisites)
2. [Build](#build)
3. [Run](#run)
4. [Notices](#notices)
4. [Usage](#usage)
1. [Configuration file](#configuration-file)
1. [EWS Settings](#ews-settings)
2. [Test bridge on one node](#test-bridge-on-one-node)
3. [Both sides use the same EWS server](#both-sides-use-the-same-ews-server)
4. [Each side uses its own EWS server](#each-side-uses-its-own-ews-server)
2. [Git Bundle Mode](#git-bundle-mode)
1. [Case 1. Existing repo on Side 1 and new empty repo on Side 2
](#case-1-existing-repo-on-side-1-and-new-empty-repo-on-side-2)
2. [Case 2. Changes are committed on Side 1, need to be pushed to Side 2
](#case-2-changes-are-committed-on-side-1-need-to-be-pushed-to-side-2)
3. [Git Email Mode](#git-email-mode)
1. [Get full patch set from the beginning](#get-full-patch-set-from-the-beginning)
2. [Get partial patch set from tagged commit](#get-partial-patch-set-from-tagged-commit)
3. [Restore the patch set](#restore-the-patch-set)
4. [Post-Receive Script](#post-receive-script)
5. [Tune Logging](#tune-logging)
5. [References](#references)
6. [TODO](#todo)

The Short Explanation
---------------------

Expand All @@ -24,7 +55,7 @@ initial conditions:
non-detectable (encrypted) attachments.
* Only files (not sub-folders) are synchronized between computers. That's
by design limitation, b/c application's `inbox` and `outbox` purpose is to
temporarily keep VCS (Git) patches or bundles that in fact is plain list, so
temporarily keep VCS ([Git]) patches or bundles that in fact is plain list, so
that any kind of file hierarchy support is business of VCS.

How It Works In A Nutshell
Expand Down Expand Up @@ -54,7 +85,7 @@ Both sides have symmetric settings and work in absolutely the same manner.
So the main flow may look like that:

1. User of "Side 1" puts file or files into `outbox` folder (these files are
intended to be the result of Git command - see the **"Usage"** section below
intended to be the result of [Git] command - see the **"Usage"** section below
for details).
2. App on "Side 1" detects that new files are appeared in `outbox` and creates
new Email message(s) where attaches these files (packed and/or encrypted if
Expand All @@ -64,7 +95,7 @@ So the main flow may look like that:
4. App on "Side 2" detects that new email is available, so receives it and
processes to obtain files from attachments and puts these files into `inbox`
folder in its original representation (decrypted and/or unpacked).
5. User of "Side 2" runs appropriate commands (e.g. Git) to apply new changes
5. User of "Side 2" runs appropriate commands (e.g. [Git]) to apply new changes
represented by these files, and cleans up the `inbox` folder.

The last point may be automated as well - see **"Post-Receive Script"** section
Expand All @@ -75,12 +106,18 @@ Build And Run

### Prerequisites ###

To build and run this application you need:
To build this application you need:

* Java 7+;
* Maven 3+;
* JDK 7+;
* [Maven](https://maven.apache.org/) 3+;
* Internet connection.

To run:

* JRE/JDK 7+;
* [Git];
* If OS is Windows - [Cygwin] - optional but recommended.

### Build ###

This project is Maven-driven, so all what you need to do to build it is to run
Expand All @@ -89,19 +126,17 @@ the following command:
$ mvn clean package

### Run ###

If build is successful, you can run the resulting JAR file as standalone Java
app like that:

$ java -jar target/email-bridge-X.X.X-standalone.jar

Where `X.X.X` is current version number.
$ java -jar target/email-bridge-0.1.2-standalone.jar

The invocation w/o arguments will show an error that proper configuration file
is required. Just in case - you can get the short help about supported command
line arguments by specifying `-h` option:

$ java -jar target/email-bridge-X.X.X-standalone.jar -h
$ java -jar target/email-bridge-0.1.2-standalone.jar -h

### Notices ###

Expand Down Expand Up @@ -457,12 +492,14 @@ References
3. [Prepare patches for e-mail submission][git-format-patch]
4. [Apply a series of patches from a mailbox][git-am]
5. [Cygwin Project][Cygwin]
6. [Git VCS][Git]

[ews-java-api]: https://github.com/OfficeDev/ews-java-api
[git-bundle]: http://git-scm.com/docs/git-bundle
[git-format-patch]: http://git-scm.com/docs/git-format-patch
[git-am]: http://git-scm.com/docs/git-am
[Cygwin]: http://cygwin.org/
[Git]: https://git-scm.com/downloads

TODO
----
Expand Down
7 changes: 7 additions & 0 deletions data/config-template.properties
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,10 @@ email.recipients.to =
# If file size is bigger, it will be split to several parts.
# Default value is 5.
#email.attach.max.size =

# Optional path to PID file.
# If PID file is specified but cannot be created/rewritten then application stops with error.
#pid.file =

# Whether to keep or not the PID file on application finish. Default value is "false".
#pid.file.keep =
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.exchange.git</groupId>
<artifactId>email-bridge</artifactId>
<version>0.1.1</version>
<version>0.1.2</version>
<packaging>jar</packaging>

<name>email-bridge</name>
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/mail/bridge/AbstractMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@
/**
* @author <a href="mailto:max@dominichenko.com">Maksym Dominichenko</a>
*/
@SuppressWarnings("UnusedReturnValue")
public abstract class AbstractMonitor {

private final Map<Class<? extends Message<?>>, List<MonitorCallback<?>>> callbacks = new HashMap<>();

protected <T> AbstractMonitor addCallback(Class<? extends Message<T>> messageClass, MonitorCallback<T> callback) {
<T> AbstractMonitor addCallback(Class<? extends Message<T>> messageClass, MonitorCallback<T> callback) {
if (callback != null) {
List<MonitorCallback<?>> callbackList = callbacks.get(messageClass);
if (callbackList == null) {
Expand All @@ -50,7 +51,7 @@ protected <T> AbstractMonitor addCallback(Class<? extends Message<T>> messageCla
}

@SuppressWarnings({"unchecked", "SuspiciousMethodCalls"})
protected <T> void postMessage(Message<T> message) {
<T> void postMessage(Message<T> message) {
List callbackList = Utils.ensureEmpty(callbacks.get(message.getClass()));
for (MonitorCallback<T> callback : (List<MonitorCallback<T>>) callbackList)
callback.onMessage(message);
Expand Down
83 changes: 51 additions & 32 deletions src/main/java/org/mail/bridge/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ public class Config {
private final String emailAttachExtEnc;
private final int emailAttachMaxSize;

private final String pidFile;
private final boolean pidFileKeep;

public Config(String propertiesFileName) throws IOException {
Properties config = new Properties();
config.load(new FileInputStream(propertiesFileName));
Expand Down Expand Up @@ -165,133 +168,145 @@ public Config(String propertiesFileName) throws IOException {
emailAttachExtEnc = checkExt(s.isEmpty() ? ".enc" : s);
s = config.getProperty("email.attach.max.size", "");
emailAttachMaxSize = s.isEmpty() ? 5 : Integer.parseInt(s);

pidFile = config.getProperty("pid.file", "");
s = config.getProperty("pid.file.keep", "");
pidFileKeep = !s.isEmpty() && Boolean.parseBoolean(s);
}

public String getEwsEmail() {
String getEwsEmail() {
return ewsEmail;
}

public String getEwsDomain() {
String getEwsDomain() {
return ewsDomain;
}

public String getEwsUsername() {
String getEwsUsername() {
return ewsUsername;
}

public String getEwsPassword() {
String getEwsPassword() {
return ewsPassword;
}

public String getEwsServer() {
String getEwsServer() {
return ewsServer;
}

public int getEwsViewSize() {
int getEwsViewSize() {
return ewsViewSize;
}

public int getEwsSubscriptionLifetime() {
int getEwsSubscriptionLifetime() {
return ewsSubscriptionLifetime;
}

public String getProxyHost() {
String getProxyHost() {
return proxyHost;
}

public int getProxyPort() {
int getProxyPort() {
return proxyPort;
}

public String getProxyUsername() {
String getProxyUsername() {
return proxyUsername;
}

public String getProxyPassword() {
String getProxyPassword() {
return proxyPassword;
}

public String getProxyDomain() {
String getProxyDomain() {
return proxyDomain;
}

public String getOutboxFolder() {
String getOutboxFolder() {
return outboxFolder;
}

public boolean isOutboxCleanup() {
boolean isOutboxCleanup() {
return outboxCleanup;
}

public String getOutboxFileRegexp() {
String getOutboxFileRegexp() {
return outboxFileRegexp;
}

public String getInboxFolder() {
String getInboxFolder() {
return inboxFolder;
}

public String getInboxScript() {
String getInboxScript() {
return inboxScript;
}

public int getInboxScriptStopCode() {
int getInboxScriptStopCode() {
return inboxScriptStopCode;
}

public boolean isEmailInboxCleanup() {
boolean isEmailInboxCleanup() {
return emailInboxCleanup;
}

public String getEmailTagIncoming() {
String getEmailTagIncoming() {
return emailTagIncoming;
}

public String getEmailTagOutgoing() {
String getEmailTagOutgoing() {
return emailTagOutgoing;
}

public MessageFormat getEmailSubjectFormat() {
MessageFormat getEmailSubjectFormat() {
return emailSubjectFormat;
}

public MessageFormat getEmailBodyFormat() {
MessageFormat getEmailBodyFormat() {
return emailBodyFormat;
}

public String[] getEmailRecipientsTo() {
String[] getEmailRecipientsTo() {
return emailRecipientsTo;
}

public String[] getEmailRecipientsCc() {
String[] getEmailRecipientsCc() {
return emailRecipientsCc;
}

public String[] getEmailRecipientsBcc() {
String[] getEmailRecipientsBcc() {
return emailRecipientsBcc;
}

public String getEmailAttachPassword() {
String getEmailAttachPassword() {
return emailAttachPassword;
}

public boolean isEmailAttachGzip() {
boolean isEmailAttachGzip() {
return emailAttachGzip;
}

public String getEmailAttachExtGzip() {
String getEmailAttachExtGzip() {
return emailAttachExtGzip;
}

public String getEmailAttachExtEnc() {
String getEmailAttachExtEnc() {
return emailAttachExtEnc;
}

public int getEmailAttachMaxSize() {
int getEmailAttachMaxSize() {
return emailAttachMaxSize;
}

public Map<String, String> asEnvironmentMap() {
String getPidFile() {
return pidFile;
}

boolean isPidFileKeep() {
return pidFileKeep;
}

Map<String, String> asEnvironmentMap() {
Map<String, String> result = new HashMap<>();
result.put("EWS_EMAIL", ewsEmail);
result.put("EWS_DOMAIN", ewsDomain);
Expand Down Expand Up @@ -324,6 +339,8 @@ public Map<String, String> asEnvironmentMap() {
result.put("EMAIL_ATTACH_EXT_GZIP", emailAttachExtGzip);
result.put("EMAIL_ATTACH_EXT_ENC", emailAttachExtEnc);
result.put("EMAIL_ATTACH_MAX_SIZE", "" + emailAttachMaxSize);
result.put("PID_FILE", pidFile);
result.put("PID_FILE_KEEP", "" + pidFileKeep);
return result;
}

Expand Down Expand Up @@ -367,6 +384,8 @@ public String toString() {
",\n\temailAttachExtGzip='" + emailAttachExtGzip + '\'' +
",\n\temailAttachExtEnc='" + emailAttachExtEnc + '\'' +
",\n\temailAttachMaxSize=" + emailAttachMaxSize +
",\n\tpidFile='" + pidFile + '\'' +
",\n\tpidFileKeep=" + pidFileKeep +
'}';
}
}
Loading

0 comments on commit 42372e5

Please sign in to comment.