diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3f1c084..0000000 --- a/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -/nbproject/ -/build/ -/dist/ -/workingdirectory/ -build.xml -.idea -target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties -# https://github.com/takari/maven-wrapper#usage-without-binary-jar -.mvn/wrapper/maven-wrapper.jar diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0a04128..0000000 --- a/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF deleted file mode 100644 index 7def224..0000000 --- a/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: net.sharksystem.asap.cmdline.CmdLineUI - diff --git a/README.md b/README.md deleted file mode 100644 index 2c69f94..0000000 --- a/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# ASAPJava -Asynchronous Semantic Ad-hoc Protocol (ASAP) engine for Java - -# Maven Guide -## Compile and run tests -``` -mvn clean package -``` -This compiles all files, runs tests and, if they succeed, compiles the jar. The compiled jar (ASAPJava-{Version}.jar) will be in your target/ folder. - -## Compile without tests -This is needed in case you want to build the jar while your tests fail (which currently, they do fail). -``` -mvn clean package -DskipTests -``` - -# Wiki -Visit [the wiki](https://github.com/SharedKnowledge/ASAPJava/wiki) for all other information on what ASAP is and how to use it. diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c741881 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/build.xml b/build.xml deleted file mode 100644 index 36e6bf1..0000000 --- a/build.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - Builds, tests, and runs the project ASP3Java. - - - diff --git a/index.md b/index.md new file mode 100644 index 0000000..934b1d7 --- /dev/null +++ b/index.md @@ -0,0 +1,37 @@ +## Welcome to GitHub Pages + +You can use the [editor on GitHub](https://github.com/SharedKnowledge/ASAPJava/edit/gh-pages/index.md) to maintain and preview the content for your website in Markdown files. + +Whenever you commit to this repository, GitHub Pages will run [Jekyll](https://jekyllrb.com/) to rebuild the pages in your site, from the content in your Markdown files. + +### Markdown + +Markdown is a lightweight and easy-to-use syntax for styling your writing. It includes conventions for + +```markdown +Syntax highlighted code block + +# Header 1 +## Header 2 +### Header 3 + +- Bulleted +- List + +1. Numbered +2. List + +**Bold** and _Italic_ and `Code` text + +[Link](url) and ![Image](src) +``` + +For more details see [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/). + +### Jekyll Themes + +Your Pages site will use the layout and styles from the Jekyll theme you have selected in your [repository settings](https://github.com/SharedKnowledge/ASAPJava/settings). The name of this theme is saved in the Jekyll `_config.yml` configuration file. + +### Support or Contact + +Having trouble with Pages? Check out our [documentation](https://docs.github.com/categories/github-pages-basics/) or [contact support](https://support.github.com/contact) and we’ll help you sort it out. diff --git a/manifest.mf b/manifest.mf deleted file mode 100644 index 573d5a1..0000000 --- a/manifest.mf +++ /dev/null @@ -1,4 +0,0 @@ -Manifest-Version: 1.0 -X-COMMENT: Main-Class will be added automatically by build -Main-Class: net.sharksystem.asap.cmdline.CmdLineUI - diff --git a/nbbuild.xml b/nbbuild.xml deleted file mode 100644 index 8da9ded..0000000 --- a/nbbuild.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - Builds, tests, and runs the project ASP3Java. - - - diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 2b2da25..0000000 --- a/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - net.sharksystem - ASAPJava - 0.7.0 - - - 8 - 8 - 5.8.1 - 1.8.1 - 0.7.0 - - - - - junit - junit - 4.13.2 - test - - - - - org.junit.jupiter - junit-jupiter-engine - 5.8.1 - test - - - - - commons-io - commons-io - 2.11.0 - - - - - - com.sun.xml.bind - jaxb-impl - 3.0.2 - - - org.junit.platform - junit-platform-suite-api - 1.8.1 - test - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.1 - - - - - \ No newline at end of file diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF deleted file mode 100644 index 7def224..0000000 --- a/src/main/java/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: net.sharksystem.asap.cmdline.CmdLineUI - diff --git a/src/main/java/net/sharksystem/SharkException.java b/src/main/java/net/sharksystem/SharkException.java deleted file mode 100644 index f084173..0000000 --- a/src/main/java/net/sharksystem/SharkException.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.sharksystem; - -public class SharkException extends Exception { - public SharkException() { super(); } - public SharkException(String message) { - super(message); - } - public SharkException(String message, Throwable cause) { - super(message, cause); - } - public SharkException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/net/sharksystem/SharkNotSupportedException.java b/src/main/java/net/sharksystem/SharkNotSupportedException.java deleted file mode 100644 index 81dce3a..0000000 --- a/src/main/java/net/sharksystem/SharkNotSupportedException.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem; - -public class SharkNotSupportedException extends RuntimeException { - public SharkNotSupportedException() { - super(); - } - public SharkNotSupportedException(String message) { - super(message); - } - public SharkNotSupportedException(String message, Throwable cause) { - super(message, cause); - } - public SharkNotSupportedException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAP.java b/src/main/java/net/sharksystem/asap/ASAP.java deleted file mode 100644 index 821207a..0000000 --- a/src/main/java/net/sharksystem/asap/ASAP.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.sharksystem.asap; - -import java.util.Random; - -public class ASAP { - public static final int TRANSIENT_ERA = Integer.MAX_VALUE; - public static final int INITIAL_ERA = 0; - public static final int MIN_ERA = INITIAL_ERA; - public static final int MAX_ERA = Integer.MAX_VALUE-1; - - public static int nextEra(int workingEra) { - if(workingEra == ASAP.MAX_ERA) { - return ASAP.INITIAL_ERA; - } - return workingEra+1; - } - - public static int previousEra(int workingEra) { - if(workingEra == ASAP.INITIAL_ERA) { - return ASAP.MAX_ERA; - } - return workingEra-1; - } - - /** - * produces a unique id - is made up by current time in millis added with some random digits. - * @return - */ - public static String createUniqueID() { - long now = System.currentTimeMillis(); - long nowUnchanged = now; - - /* now is a 64 bit value. Actually, only 63 bits are relevant because it is positive value. - Moreover, we are already in the 21. century - could reduce bit even more. We ignore that obvious fact - at first. - - Calculations: 2^64 = 1,8.. * 10^19; we take a..z and A..Z and 0..9 -> 62 digits - 62^11 = 5,2.. * 10^19 we need 11 digits - */ - - int randomDigits = 3; - int timeDigits = 11; - int digits = timeDigits + randomDigits; - int basis = 62; - - /* - 0..9 --> 0..9 - 10..35 -> a..z - 36..61 -> A..Z - */ - - char[] idChars = new char[digits]; - // init with random number - for(int i = 0; i < digits; i++) idChars[i] = '0'; - - // let's fill it with code time stamp - int i = 0; - long rest = 0; - while(now > 0) { - rest = now % basis; // rest is number [0,63] - now /= basis; - - idChars[i++] = ASAP.int2charID((int) rest); - } - - // set index - i = timeDigits; - - // random digits - long rValue = now + nowUnchanged; - Random random = new Random(rValue); - //char lastC = ' '; // not value space - while(i < digits) { - int r = random.nextInt(basis); - char c = ASAP.int2charID(r); - //if(c == lastC) continue; - idChars[i++] = c; - rValue = (rValue * r * nowUnchanged) % basis; - random = new Random(rValue); - //random.setSeed(rValue); - } - - return new String(idChars); - } - - private static char int2charID(int value) { - // convert value into valid values; - // 0..9 -> 0..9 - if(value <= 9) { - return (char)((int)'0' + value); - } else { - value -= 10; - // a..z - if(value <= 25) { - return (char)((int)'a' + value); - } else { - // A..Z - value -= 26; - return (char)((int)'A' + value); - } - } - } - - /** - * - * This method test if an era is within (or on the edge of) an era - range described by first and last era. - * @param era era that is tested. Is in within a given range - * @param eraFirst first era of that range. - * @param eraLast last era of that range - * @return true - era is in that range or on the edge, false otherwise - */ - public static boolean isEraInRange(int era, int eraFirst, int eraLast) { - // deal wrapping around era numbers - if(eraLast - eraFirst >= 0) { // not wrapped around - // [init].... [eraFirst] ++++ [eraLast] ..... [max] - return (era >= eraFirst && era <= eraLast); - } - // else: wrapped around: - /* - [init]++++++++++++++ [eraLast] .......... [eraFirst] +++++++++[max] - (a) (b) (c) - */ - return ( - isEraInRange(era, eraFirst, ASAP.MAX_ERA) // c) - || - isEraInRange(era, ASAP.INITIAL_ERA, eraLast) // a) - ); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPChannel.java b/src/main/java/net/sharksystem/asap/ASAPChannel.java deleted file mode 100644 index fe995ea..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPChannel.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.sharksystem.asap; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Set; - -public interface ASAPChannel { - CharSequence getOwner() throws IOException; - CharSequence getUri() throws IOException; - Set getRecipients() throws IOException; - HashMap getExtraData() throws IOException; - void putExtraData(String key, String value) throws IOException; - void removeExtraData(String key) throws IOException; - - /** - * Get all message in this channel, including received messages. Same as getMessages(true); - * @return - * @throws IOException - */ - ASAPMessages getMessages() throws IOException; - - /** - * Get messages in this channel only (most probably sent) from this peer or also received messages - * @param sentMessagesOnly - * @return - * @throws IOException - */ - ASAPMessages getMessages(boolean sentMessagesOnly) throws IOException, ASAPException; - - /** - * Get all message (including received messages). Compare Object helps to bring messages in order. - * - * @param compare - * @return - * @throws IOException - */ - ASAPMessages getMessages(ASAPMessageCompare compare) throws IOException, ASAPException; - - /** - * Add a message to this channel - in other words: broadcast a message into this channel. - * @param message - * @throws IOException - */ - void addMessage(byte[] message) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListener.java b/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListener.java deleted file mode 100644 index 49339c6..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.sharksystem.asap; - -public interface ASAPChannelContentChangedListener { - void asapChannelContentChanged(CharSequence format, CharSequence uri, int era); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListenerManagement.java b/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListenerManagement.java deleted file mode 100644 index 7724bb1..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPChannelContentChangedListenerManagement.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap; - -public interface ASAPChannelContentChangedListenerManagement { - /** - * Add listener for changes in ASAP environment - * @param listener listener which is to be added - */ - void addASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener); - - /** - * Remove changes listener - * @param listener listener which is to be removed - */ - void removeASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener); - -} diff --git a/src/main/java/net/sharksystem/asap/ASAPChunk.java b/src/main/java/net/sharksystem/asap/ASAPChunk.java deleted file mode 100644 index 515ac33..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPChunk.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.engine.MessagesContainer; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -/** - * An ASAP chunk is a set of message with the same format, same uri and same era. - * - * Usually, there will be a running ASAP protocol engine that writes received messages into - * chunks and delivers chunks to peers during an encounter - * - * @author thsc - */ -public interface ASAPChunk extends MessagesContainer { - /** - * - * @return number of message in that chunk - */ - int getNumberMessage(); - - /** - * URI of all messages within that chunk - * @return - * @throws IOException - */ - String getUri() throws IOException; - - /** - * - * @return iterator of all messages in the chunk - * @throws IOException - */ - Iterator getMessages() throws IOException; - - /** - * remove that chunk.. drop all object references after - * calling this methods. Further calls on this object - * have an undefined behaviour. - */ - public void drop(); - - /** - * - * @return era all messages in that chunk - * @throws IOException - */ - public int getEra() throws IOException; - - /** - * Handle this methode with great care. - * It will most probable disappear of we find time to re-implement the PKI projects. Until then: - *

- * A chunk behaves like an in- or outbox in an mail system. Sometimes a chunk is both. - * An ASAP peer offers a send message which is the preferred and recommended way to send messages. - *

- * A peer behaves pretty simple internally. A message that is ought to be sent is stored in - * a chunk with current era. Received messages are stored in chunks as well. There is no need - * to change those chunks from any application. - *

- * Peers can also be asked to re-deliver received messages. In that case, an application could think - * of managing such chunks to drop message (usually whole chunks) which are not meant to be - * re-delivered. Actually, it is not a really good idea. But we did. And we haven't not yet found time - * to take it out. And we need a running public key infrastructure. - *

- * Furthermore, an ASAP peer keeps a list of its encounters. It can figure out the last era - * in which another peer was met. If they have never met before the initial era would be taken in - * its place. - *

- * Now, default behaviour of a peer is to transmit all messages from this last-met-era - * until current era. - *

- * Sometimes, it seemed to be efficient to manipulate those chunks to slightly change the set - * of delivered messages. I our decentralized PKI, we decided to implement the certificate - * storage as decorator of a chunk storage. That's actually quite efficient but requires - * a lot of explaining and hinders us to change the internal structure. - *

- * Unfortunately, it forced us to make this feature public. And here we are. You can add a message - * to a chunk. You should not do it until you are absolutely sure what you are doing. - * It is something of a hack. Efficient yet but not good. - * - * @param messageAsBytes - * @throws IOException - * @see net.sharksystem.asap.ASAPPeer#sendASAPMessage(CharSequence, CharSequence, byte[]) - */ - void addMessage(byte[] messageAsBytes) throws IOException; - - List getASAPHopList(); - -} diff --git a/src/main/java/net/sharksystem/asap/ASAPChunkStorage.java b/src/main/java/net/sharksystem/asap/ASAPChunkStorage.java deleted file mode 100644 index dba4fce..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPChunkStorage.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.engine.ASAPInternalChunk; - -import java.io.IOException; -import java.util.List; - -/** - * There is a chunk storage for each format. It offers methods - * to get (and create) and remove (drop) chunks. - * - * Be careful. In most cases, there will be an ASAP protocol engine that writes data - * in chunks and reads and transmits messages to encountered peers. - * - * @author thsc - */ -public interface ASAPChunkStorage { - String getFormat(); - - ASAPInternalChunk getChunk(CharSequence uri, int era) throws IOException; - - boolean existsChunk(CharSequence uri, int era) throws IOException; - - List getChunks(int era) throws IOException; - - void dropChunks(int era) throws IOException; - - /** - * - * @param uri chunk storage uri - * @param toEra newest era - * @return a chunk cache which hides details of era - * @throws IOException - */ - ASAPMessages getASAPMessages(CharSequence uri, int toEra) throws IOException; - - ASAPMessages getASAPMessages(CharSequence uri, int fromEra, int toEra) throws IOException; - - ASAPMessages getASAPMessages(String uri) throws ASAPException, IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPConnectionHandler.java b/src/main/java/net/sharksystem/asap/ASAPConnectionHandler.java deleted file mode 100644 index b1c0145..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPConnectionHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.protocol.ASAPConnection; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Set; - -public interface ASAPConnectionHandler { - /** - * Ask the entity to run an ASAP session based on this point-to-point connection. - * @param is stream to read from - * @param os stream to write into - * @param encrypt encrypt this point-to-point communication - * @param sign sign this point-to-point communication - * @param appsWhiteList if not null - only message from this app (synonym: with this format) - * within that list are handled. All other messages are ignored - * @param appsBlackList if not null - message from this app (synonym: with this format) - * are not handled. Overwrites white list entries. - * @return - * @throws IOException - * @throws ASAPException - */ - ASAPConnection handleConnection( - InputStream is, OutputStream os, boolean encrypt, boolean sign, - Set appsWhiteList, Set appsBlackList - ) throws IOException, ASAPException; - - ASAPConnection handleConnection( - InputStream is, OutputStream os, boolean encrypt, boolean sign, ASAPEncounterConnectionType connectionType, - Set appsWhiteList, Set appsBlackList - ) throws IOException, ASAPException; - - /** - * - * Ask the entity to run an ASAP session based on this point-to-point connection. Message are neither - * encrypted nor signed. All formats are accepted in principle. - * @param is stream to read from - * @param os stream to write into - * @return - * @throws IOException - * @throws ASAPException - */ - ASAPConnection handleConnection(InputStream is, OutputStream os) throws IOException, ASAPException; - - ASAPConnection handleConnection(InputStream inputStream, OutputStream outputStream, - ASAPEncounterConnectionType connectionType) throws IOException, ASAPException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPEncounterConnectionType.java b/src/main/java/net/sharksystem/asap/ASAPEncounterConnectionType.java deleted file mode 100644 index ee533f2..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPEncounterConnectionType.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.sharksystem.asap; - -public enum ASAPEncounterConnectionType { - UNKNOWN ((byte) 0), - AD_HOC_LAYER_2_NETWORK ((byte) 1), - ASAP_HUB ((byte) 2), - INTERNET ((byte) 3), - ONION_NETWORK ((byte) 4); - - private final byte type; - - ASAPEncounterConnectionType(byte type) { - this.type = type; - } - - public String toString() { - switch(this.type) { - case 0: return "unknown"; - case 1: return "ad-hoc"; - case 2: return "hub"; - case 3: return "internet"; - case 4: return "onion"; - default: return "
- * We could of course ignore this somewhat more complex environment and create a connection whenever possible and - * run an ASAP session. That not very efficient, though. It has even the tendency to be a considerable wast of - * resources. Why is that? - *

- * Take ad-hoc networks as an example: A connection can be established within a given radius, like 10m with Bluetooth. - * A connection gets lost if two devices are over that threshold and can be re-established if they get closer. This - * leads to flickering effects. Connection gone / re-established / gone again etc. That's ok and useful if we are about - * implementing streaming services. But we war not. ASAP is basically meant to be platform for distributed apps which - * are based on the command pattern. There are no streams but data packages. - *

- * Application developers will have a pretty good understanding of how often such messages are created. Even very fast - * human writers will barely produce more than a message per second, presumably far less. Exchange rate in a sensor - * network observing outside temperature is better be measured in hours than minutes. This will be different in - * industrial processes. Apparently: It depends on the application scenario. We want to give application developers - * as much help for optimization as possible. That is one way to safe most probably a lot of energy. - *

- * ASAP is an opportunistic protocol. Connections should be established whenever possible. This could and will be a - * serious leak on resources in a multi-protocol environment. It is hardly useful that two smartphones create a - * Bluetooth and a Wifi-direct connection if they can. One is sufficient. - *

- * An encounter manager deals with those problems. It is highly recommended to use it. We do, see e.g. our ASAPAndroid - * lib which is even more highly recommend. - */ -public interface ASAPEncounterManager { - /** - * Other devices can be detected by a point-to-point protocol. This method is to be called before a connection - * is established. - *

- * It can be checked when a last encounter happened. This is most useful e.g. in ad-hoc networks. Communication can - * get lost by a (slight) movement and could be reestablished a moment later. A kind of cool-down-period can be - * defined. - *

- * Peers could communicate over different channels. Same argument: It can be decided not to establish - * a connection due to an existing one over another protocol. - * @param addressOrPeerID address of remote device or a peer id. It is only used as an index, an id. - * There will be no attempts to establish a connection. - * @param connectionType Describes the connection that is planned to be established. - * @return true: a connection should be established or not. - * @see ASAPEncounterConnectionType - */ - boolean shouldCreateConnectionToPeer(CharSequence addressOrPeerID, ASAPEncounterConnectionType connectionType); - - /** - * Encounter manager forgets about its previous encounter. It will re-connect whenever possible. - * Gives peers a chance enforce reconnection if something changed o their side. - */ - void forgetPreviousEncounter(); - - /** - * A connection to another device was established. This method can be called to handle this new connection. - * It can lead to an immediate shutdown, e.g. the other device already made a successful attempt to connect e.g. - * over another protocol. - *

- * In a lot of cases an ASAP session will be launched. - * - * @param streamPair most likely a socket that is can be used for an ASAP session. - * @throws IOException something can go wrong when sending data. This object has no obligation to deal with this. - */ - void handleEncounter(StreamPair streamPair, ASAPEncounterConnectionType connectionType) throws IOException; - - /** - * This method is a variant of the one with less parameters. - * - * Here is the catch: - *

- * We have a race condition in any ad-hoc network based on this library. What happens if both devices come into - * sending range? - *

- *
    - *
  • Each asks this object if it should establish a connection by calling shouldConnect. It is highly likely - * that both side get same answer. Let's assume it is a yes.
  • - *
  • Both would open a passive endpoint (most likely a server socket). In most cases it is already open - * before the previous step. In any case..
  • - *
  • Both would try to establish a connection to the other side... An here starts the race...
  • - *
  • Let's assume Alice and Bob are in that situation: Alice would recognize an connection attempt from - * Bob on her server socket. She is also aware that she is also doing a connection attempt to Bob. That's in the - * nature of this process. We do not want this. We do not want to parallel connections between those two devices. - * One should be canceled. But what: Alice -> Bob or Bob -> Alice ?
  • - *
  • Bob is in the same situation. That problem arose when working with Bluetooth. It happens very often. - * This simple solution does not work: If we see a connection attempt on our server we drop out active - * connection attempt. Both side would do the same and both connection attempts are canceled. That is the race - * condition. - *
  • - *
- * - * This problem can be solved by adding an additional parameter. This boolean value states if this method is - * called by an initiator. What is that? A process that create e.g. a client socket is - per definition - - * an initiator. It initiated this connection. A server socket waits for connection attempts and is - * - per definition - no initiator. Please, choose very carefully this parameter. The race condition is solved - * by an implementation of this interface. - *

- * If you are interested: Here is an idea of an implementation. - *
    - *
  • It is checked if there is an open connection to the other side before anything other happens. - * If so: stream pair is closed and we are ready here.
  • - *
  • Both sides exchange a random value over this stream pair. One side will be initiator - the other not. - * (If you chose that parameter carefully). No we can decide: - * What is the random number of the initiator and what is the non-initiator value.
  • - *
  • Is the initiator value smaller than the non-initial value? If so: - * We let this thread sleep a little while. We have produced an asymmetry. One process waits, the other not. - *
  • - *
  • After wake-up: We check again if there is already a connection established. If so - there was a race - * condition and we solved it. If not - we establish a connection.
  • - *
- * - * You should call this variant in any ad-hoc network. You should also uses this variant if you have a fully - * symmetric situation - both devices offer a port to connect to any make and active attempt to connect. - * - * @param streamPair - * @param initiator - * @throws IOException - * @see ASAPEncounterManager#handleEncounter(StreamPair, ASAPEncounterConnectionType) - */ - void handleEncounter(StreamPair streamPair, ASAPEncounterConnectionType connectionType, boolean initiator) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPEncounterManagerAdmin.java b/src/main/java/net/sharksystem/asap/ASAPEncounterManagerAdmin.java deleted file mode 100644 index dcf6120..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPEncounterManagerAdmin.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.sharksystem.asap; - -import java.util.Date; -import java.util.Map; -import java.util.Set; - -/** - * That's the admin interface of an encounter manager. It allows deny list management. - * A deny list contains peerIDs. The encounter manager must not establish new connections to - * those peers. There can be several reasons (security (peer is not considered trustworthy), - * network topology (see considerations of a large scale ad-hoc network with limited - * connections on each peer). - * - * Future enhancements: - *
  • define a point to point encryption policy.
  • - *
  • define what connections types are acceptable (Internet, Hub, Ad-hoc, Onion)
- */ -public interface ASAPEncounterManagerAdmin { - /** - * @return set of ID to which an open connection exists right now. - */ - Set getConnectedPeerIDs(); - - /** - * - * @param peerID peerID - * @return connection type of existing connection with given peer - * @throws ASAPException if no connection to that peer exists - */ - ASAPEncounterConnectionType getConnectionType(CharSequence peerID) throws ASAPException; - - /** - * Add a peerID to what no connection should be established. - * Note: Adding a peer to the deny list does not necessarily terminate an - * existing connection to that peer. - * @param peerID - */ - void addToDenyList(CharSequence peerID); - - /** - * Remove a peerID from deny list - * @param peerID - */ - void removeFromDenyList(CharSequence peerID); - - /** - * Get PeerID set to which no connection should be established - * @return - */ - Set getDenyList(); - - /** - * remove all entries from deny list - */ - void clearDenyList(); - - /** - * Cancel a connection to a peer. This method call does not change the deny list. - * @param peerID - */ - void closeEncounter(CharSequence peerID); - - - /** - * - * @return information about last enocunter of a certain peer (described by its id) - */ - Map getEncounterTime(); - - /** - * Peers exchange data during an encounter. In certain circumstances, ad-hoc networks show a feature that can be - * described es flickering. Devices might have reached communication range. A little shift can lead to connection - * lost. A little move backwards can bring them back in range. Connection establishment is a time-consuming task, - * though. Each encounter manager waits a while before it re-connects to a peer. - * - * @return time in milliseconds (aka 'cool down periode') - */ - long getTimeBeforeReconnect(); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPEncounterManagerImpl.java b/src/main/java/net/sharksystem/asap/ASAPEncounterManagerImpl.java deleted file mode 100644 index 554896f..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPEncounterManagerImpl.java +++ /dev/null @@ -1,475 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.utils.DateTimeHelper; -import net.sharksystem.fs.ExtraDataFS; -import net.sharksystem.asap.protocol.ASAPConnection; -import net.sharksystem.asap.protocol.ASAPConnectionListener; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.asap.utils.PeerIDHelper; -import net.sharksystem.utils.streams.StreamPair; -import net.sharksystem.utils.Log; - -import java.io.*; -import java.util.*; - -public class ASAPEncounterManagerImpl implements - ASAPEncounterManager, ASAPEncounterManagerAdmin, ASAPConnectionListener { - public static final long DEFAULT_WAIT_BEFORE_RECONNECT_TIME = 60000; // 60 seconds == 1 minute - public static final long DEFAULT_WAIT_TO_AVOID_RACE_CONDITION = 500; // milliseconds - worked fine with BT. - public static final String DATASTORAGE_FILE_EXTENSION = "em"; - private static final CharSequence ENCOUNTER_MANAGER_DENY_LIST_KEY = "denylist"; - private final CharSequence peerID; - private ExtraDataFS extraDataStorage = null; - - private int randomValue; - private long waitBeforeReconnect; - private ASAPConnectionHandler asapConnectionHandler; // object that will eventually run the ASAP session - - /* - PeerID --[peerRemoteAddress]--(n)--> remoteAddress - remoteAddressORPeerID --[openStreamPairs]--(1)--> StreamPair - remoteAddressORPeerID --[encounterDate]--(1)--> Date - ASAPConnection --[openASAPConnections]--(1)--> remoteAddressORPeerID - */ - - /** - * We keep all open stream pairs indexed by their remote address to avoid identical connections and 'flickering' - * remote address -> stream pair - */ - private Map openStreamPairs = new HashMap<>(); - - /** open ASAP connections with their stream pair: asap connection -> remote address */ - private Map openASAPConnections = new HashMap<>(); - - /** remember last encounter: remote address -> date */ - private Map encounterDate = new HashMap<>(); - - /** remember remote address of peers (they can have more than one): peerID -> remote address */ - private Map> peerRemoteAddresses = new HashMap<>(); - - public ASAPEncounterManagerImpl(ASAPConnectionHandler asapConnectionHandler, CharSequence peerID) - throws SharkException, IOException { - this(asapConnectionHandler, peerID, DEFAULT_WAIT_BEFORE_RECONNECT_TIME); - } - - public ASAPEncounterManagerImpl(ASAPConnectionHandler asapConnectionHandler, CharSequence peerID, - long waitingPeriod, CharSequence rootFolder) throws SharkException, IOException { - this.asapConnectionHandler = asapConnectionHandler; - this.peerID = peerID; - this.randomValue = new Random(System.currentTimeMillis()).nextInt(); - this.waitBeforeReconnect = waitingPeriod; - - if(rootFolder != null && rootFolder.length() > 0) { - // create folder - this.extraDataStorage = new ExtraDataFS(rootFolder + "/" + ENCOUNTER_MANAGER_DENY_LIST_KEY, DATASTORAGE_FILE_EXTENSION); - this.restoreDenyList(); - } - } - - public ASAPEncounterManagerImpl(ASAPConnectionHandler asapConnectionHandler, CharSequence peerID, - long waitingPeriod) throws SharkException, IOException { - this(asapConnectionHandler, peerID, waitingPeriod, null); - } - - private boolean coolDownOver(CharSequence id, ASAPEncounterConnectionType connectionType) { - Date now = new Date(); - Date lastEncounter = this.encounterDate.get(id); - - if(lastEncounter == null) { - Log.writeLog(this, this.toString(), - "device/peer not in encounteredDevices - add " - + DateTimeHelper.long2ExactTimeString(now.getTime())); - // this.encounterDate.put(id, now); do not enter it into that list before (!!) a connection is established - return true; - } - - // calculate reconnection time - Log.writeLog(this, this.toString(), "this.waitBeforeReconnect == " + this.waitBeforeReconnect); - - // get current time, in its incarnation as date - long nowInMillis = now.getTime(); - long shouldReconnectIfBeforeInMillis = nowInMillis - this.waitBeforeReconnect; - Date shouldReconnectIfBefore = new Date(shouldReconnectIfBeforeInMillis); - - StringBuilder sb = new StringBuilder(); - sb.append("\n"); - sb.append(DateTimeHelper.long2ExactTimeString(nowInMillis)); - sb.append(" == now\n"); - sb.append(DateTimeHelper.long2ExactTimeString(shouldReconnectIfBeforeInMillis)); - sb.append(" == should reconnect if met before that moment\n"); - sb.append(DateTimeHelper.long2ExactTimeString(lastEncounter.getTime())); - sb.append(" == last encounter"); - Log.writeLog(this, this.toString(), sb.toString()); - - // known peer - Log.writeLog(this, this.toString(), "device/peer (" + id + ") in encounteredDevices list?"); - // it was in the list - if(lastEncounter.before(shouldReconnectIfBefore)) { - Log.writeLog(this, this.toString(), "yes - should connect: " + id); - // remember that and overwrite previous entry - /* that was a nasty bug since this method is called before establishing a connection - * AND after connection establishment and before lauching an ASAP session - */ - // this.encounterDate.put(id, now); - return true; - } - - Log.writeLog(this, this.toString(), "should not connect - recently met: " + id); - return false; - } - - @Override - public boolean shouldCreateConnectionToPeer(CharSequence remoteAdressOrPeerID, - ASAPEncounterConnectionType connectionType) { - Log.writeLog(this, this.toString(), "should connect to " + remoteAdressOrPeerID + " ?"); - // on deny list? - if(this.denyList.contains(remoteAdressOrPeerID)) return false; - Log.writeLog(this, this.toString(), remoteAdressOrPeerID + " not on deny list"); - - // do we have a connection under a peerID? - StreamPair streamPair = this.openStreamPairs.get(remoteAdressOrPeerID); - if(streamPair != null) { - return false; - } else { - Log.writeLog(this, this.toString(), remoteAdressOrPeerID + " no parallel open connection"); - } - - // we know this peer and it is still in cool down period - if(!this.coolDownOver(remoteAdressOrPeerID, connectionType)) return false; - - // is this id a remote adress? - Set remoteAddresses = this.peerRemoteAddresses.get(remoteAdressOrPeerID); - if(remoteAddresses == null) { - // we do not know this peer with no address - connect - return true; - } - - // is there an open connection with any of those addresses? - for(CharSequence remoteAddress : remoteAddresses) { - streamPair = this.openStreamPairs.get(remoteAddress); - if(streamPair != null) { - // if there is a single reason not to connect - we do not connect - if(!this.coolDownOver(remoteAddress, connectionType)) return false; - } - } - - // no open connection and cool down period over for any known address - connect - return true; - } - - @Override - public void forgetPreviousEncounter() { - this.encounterDate = new HashMap<>(); - } - - @Override - public void handleEncounter(StreamPair streamPair, ASAPEncounterConnectionType connectionType) throws IOException { - this.handleEncounter(streamPair, connectionType, false, false); - } - - @Override - public void handleEncounter(StreamPair streamPair, ASAPEncounterConnectionType connectionType, boolean initiator) - throws IOException { - - this.handleEncounter(streamPair, connectionType, initiator, true); - } - - @Override - public Map getEncounterTime() { - return this.encounterDate; - } - - @Override - public long getTimeBeforeReconnect() { - return this.waitBeforeReconnect; - } - - private void handleEncounter(StreamPair streamPair, ASAPEncounterConnectionType connectionType, boolean initiator, - boolean raceCondition) throws IOException { - // always exchange peerIDs - DataOutputStream dos = new DataOutputStream(streamPair.getOutputStream()); - dos.writeUTF(this.peerID.toString()); - DataInputStream dis = new DataInputStream(streamPair.getInputStream()); - String remotePeerID = dis.readUTF(); - - if(remotePeerID != null && remotePeerID.length() > 0) { - streamPair.setEndpointID(remotePeerID); - } - - CharSequence connectionID = streamPair.getEndpointID(); - if(connectionID == null || connectionID.length() == 0) connectionID = streamPair.getSessionID(); - - Log.writeLog(this, this.toString(), "decide whether to pursue this new encounter: " + streamPair); - - // should we connect in the first place - if (!this.shouldCreateConnectionToPeer(connectionID, connectionType)) { - // no - than shut it down. - Log.writeLog(this, this.toString(), - "close connection (on deny list or in cool down)"); - streamPair.close(); - return; - } - - // new stream pair is ok. Is there a race condition expected ? - if(raceCondition) { - // avoid the nasty race condition - Log.writeLog(this, this.toString(), "solve race condition"); - boolean waited = this.solveRaceCondition(streamPair, initiator, DEFAULT_WAIT_TO_AVOID_RACE_CONDITION); - - // ask again? - if (waited) { - if (!this.shouldCreateConnectionToPeer(connectionID, connectionType)) { - streamPair.close(); - return; - } - } - } - - // we are through with it - remember that new stream pair - Log.writeLog(this, this.toString(), "remember streamPair: " + streamPair); - this.openStreamPairs.put(connectionID, streamPair); - Log.writeLog(this, this.toString(), "remember encounter: " + streamPair.getEndpointID()); - this.encounterDate.put(streamPair.getEndpointID(), new Date()); - try { - Log.writeLog(this, this.toString(), "call asap peer to handle connection"); - ASAPConnection asapConnection = - this.asapConnectionHandler.handleConnection( - streamPair.getInputStream(), streamPair.getOutputStream(), connectionType); - - asapConnection.addASAPConnectionListener(this); - - Log.writeLog(this, this.toString(), - "asap peers is handling session: " + asapConnection.toString()); - this.openASAPConnections.put(asapConnection, connectionID); - - } catch (IOException | ASAPException e) { - Log.writeLog(this, this.toString(), "while launching asap connection: " - + e.getLocalizedMessage()); - } - } - - private boolean solveRaceCondition(StreamPair streamPair, boolean connectionInitiator, - long waitInMillis) throws IOException { - // run a little negotiation before we start - DataOutputStream dos = new DataOutputStream(streamPair.getOutputStream()); - int remoteValue = 0; - String remotePeerID = null; - - try { - // write protocol unit - dos.writeInt(this.randomValue); - dos.writeUTF(this.peerID.toString()); - - // read it - DataInputStream dis = new DataInputStream(streamPair.getInputStream()); - remoteValue = dis.readInt(); - remotePeerID = dis.readUTF(); - - if(remotePeerID != null && remotePeerID.length() > 0) streamPair.setEndpointID(remotePeerID); - } catch (IOException e) { - // decision is made - this connection is dead - streamPair.close(); - } - - StringBuilder sb = new StringBuilder(); - sb.append("try to solve race condition: random (local/remote) == "); - sb.append(this.randomValue); - sb.append("/"); - sb.append(remoteValue); - sb.append(" | peerID == "); - sb.append(this.peerID); - sb.append("/"); - sb.append(remotePeerID); - sb.append(" | initiator == "); - sb.append(connectionInitiator); - - int initiatorValue, nonInitiatorValue; - if(connectionInitiator) { - initiatorValue = this.randomValue; - nonInitiatorValue = remoteValue; - } else { - initiatorValue = remoteValue; - nonInitiatorValue = this.randomValue; - } - - sb.append(" | initiatorValue == "); - sb.append(initiatorValue); - sb.append(" | nonInitiatorValue == "); - sb.append(nonInitiatorValue); - Log.writeLog(this, this.toString(), sb.toString()); - - /* Here comes the bias: An initiator with a smaller value waits a moment */ - if(connectionInitiator && initiatorValue < nonInitiatorValue) { - try { - sb = new StringBuilder(); - sb.append("wait "); - sb.append(waitInMillis); - sb.append(" ms"); - Log.writeLog(this, this.toString(), sb.toString()); - Thread.sleep(waitInMillis); - return true; // waited - } catch (InterruptedException e) { - Log.writeLog(this, this.toString(), "wait interrupted"); - } - } - - return false; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAPConnectionListener // - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public synchronized void asapConnectionStarted(String remotePeerName, ASAPConnection connection) { - CharSequence peerID = connection.getEncounteredPeer(); - Log.writeLog(this, this.toString(), "new ASAP encounter: " + connection); - - CharSequence streamPairID = this.openASAPConnections.get(connection); - if(PeerIDHelper.sameID(streamPairID, peerID)) { - // nothing to do. This connection was already established with peer id - return; - } - - // connection was established with remote address. Remember that - Set remoteAddresses = this.peerRemoteAddresses.get(peerID); - if(remoteAddresses == null) { - remoteAddresses = new HashSet<>(); - this.peerRemoteAddresses.put(peerID, remoteAddresses); - } - - remoteAddresses.add(streamPairID); - - } - - @Override - public synchronized void asapConnectionTerminated(Exception terminatingException, ASAPConnection connection) { - Log.writeLog(this, this.toString(), "encounter terminated: " + connection); - CharSequence peerID = connection.getEncounteredPeer(); - - CharSequence peerIDOrAddress = this.openASAPConnections.get(connection); - this.openASAPConnections.remove(connection); - - // one call will fail - who cares. - this.openStreamPairs.remove(peerIDOrAddress); - this.openStreamPairs.remove(peerID); - - // was this stream pair registered with remote address? Clean peerRemoteAddress data set. - Set remoteAddresses = this.peerRemoteAddresses.get(peerID); - if(remoteAddresses != null) { - // this connection was registered under its remote address - for(CharSequence remoteAddressObject : remoteAddresses) { - if(PeerIDHelper.sameID(remoteAddressObject, peerIDOrAddress)) { - // found it - if(remoteAddresses.size() == 1) { - // remove whole entry - this was its only entry - this.peerRemoteAddresses.remove(peerID); - } else { - remoteAddresses.remove(remoteAddressObject); - } - // in any case - we are ready here - break; - } - } - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // EncounterManagerAdmin // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private Set denyList = new HashSet<>(); - - //// housekeeping deny list - public void clearDenyList() { - this.denyList = new HashSet<>(); - try { - this.saveDenyList(); - } catch (IOException | SharkException e) { - Log.writeLogErr(this, this.toString(), "cannot persist deny list: " + e.getLocalizedMessage()); - } - } - private void restoreDenyList() throws SharkException, IOException { - if(this.extraDataStorage == null) { - Log.writeLog(this, this.toString(), "no persistent storage for deny list"); - } else { - byte[] denyListBytes = this.extraDataStorage.getExtra(ENCOUNTER_MANAGER_DENY_LIST_KEY); - if(denyListBytes != null && denyListBytes.length > 0) { - ByteArrayInputStream bais = new ByteArrayInputStream(denyListBytes); - this.denyList = ASAPSerialization.readCharSequenceSetParameter(bais); - } else { - this.clearDenyList(); - } - } - } - - private void saveDenyList() throws IOException, SharkException { - if(this.extraDataStorage == null) { - Log.writeLog(this, this.toString(), "no persistent storage for deny list"); - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeCharSequenceSetParameter(this.denyList, baos); - this.extraDataStorage.putExtra(ENCOUNTER_MANAGER_DENY_LIST_KEY, baos.toByteArray()); - } - } - - ///// manage deny list - @Override - public void addToDenyList(CharSequence peerID) { - this.denyList.add(peerID); - try { - this.saveDenyList(); - } catch (IOException | SharkException e) { - Log.writeLogErr(this, this.toString(), "cannot persist deny list: " + e.getLocalizedMessage()); - } - } - - @Override - public void removeFromDenyList(CharSequence peerID) { - this.denyList.remove(peerID); - try { - this.saveDenyList(); - } catch (IOException | SharkException e) { - Log.writeLogErr(this, this.toString(), "cannot persist deny list: " + e.getLocalizedMessage()); - } - } - - @Override - public Set getDenyList() { - return this.denyList; - } - - @Override - public Set getConnectedPeerIDs() { - return this.openStreamPairs.keySet(); - } - - public ASAPEncounterConnectionType getConnectionType(CharSequence peerID) throws ASAPException { - for(ASAPConnection connection : this.openASAPConnections.keySet()) { - if(PeerIDHelper.sameID(connection.getEncounteredPeer(), peerID)) { - // found our connection - return connection.getASAPEncounterConnectionType(); - } - } - throw new ASAPException("there is no connection to peer " + peerID); - } - - @Override - public void closeEncounter(CharSequence peerID) { - StreamPair stream2Close = this.openStreamPairs.get(peerID); - if(stream2Close != null) { - stream2Close.close(); - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // utils // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public String toString() { - if(this.asapConnectionHandler != null) return this.asapConnectionHandler.toString(); - else return "null"; - } - -} diff --git a/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListener.java b/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListener.java deleted file mode 100644 index eb4b52c..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListener.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.sharksystem.asap; - -import java.util.Set; - -public interface ASAPEnvironmentChangesListener { - /** - * ASAP peers establish connections on their own and usually if possible. This - * message is called if one or more connections could be established or got lost. - * @param peerList current list of peer we have a connection to (can be empty) - */ - void onlinePeersChanged(Set peerList); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListenerManagement.java b/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListenerManagement.java deleted file mode 100644 index 2d0948f..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPEnvironmentChangesListenerManagement.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.sharksystem.asap; - -public interface ASAPEnvironmentChangesListenerManagement { - /** - * Add listener for changes in ASAP environment - * @param changesListener listener which is to be added - */ - void addASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener); - - /** - * Remove changes listener - * @param changesListener listener which is to be removed - */ - void removeASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPException.java b/src/main/java/net/sharksystem/asap/ASAPException.java deleted file mode 100644 index 57a44cd..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPException.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.SharkException; - -/** - * - * @author thsc - */ -public class ASAPException extends SharkException { - public ASAPException() { super(); } - public ASAPException(String message) { - super(message); - } - public ASAPException(String message, Throwable cause) { - super(message, cause); - } - public ASAPException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPHop.java b/src/main/java/net/sharksystem/asap/ASAPHop.java deleted file mode 100644 index 9559fd9..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPHop.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.sharksystem.asap; - -/** - * Describes the exchange if an ASAP message from one peer to the other - */ -public interface ASAPHop { - /** - * Sender is always a point-to-point sender. There is no get receiver method, though. Hops are kept in a chain. - * Receiver of the last entry is local peer itself. For all hops in between: Sender of next hop is receiver of - * the previous hop. - * @return - */ - CharSequence sender(); - - /** - * An ASAP message exchange is based on a point-to-point connection. There are different options: Ad-hoc networks, - * Internet, onion networks etc. This method describes the connection type of this hop. - * @return - */ - ASAPEncounterConnectionType getConnectionType(); - - /** - * A sender could have signed the point-to-point message transfer. This message returns true if the receiver was - * able to verify the signature. A false could be indicator for a forged identity or that the receiver has not got - * sender's public key. - * @return - */ - boolean verified(); - - /** - * This point-to-point connection was encrypted. - * @return - */ - boolean encrypted(); - -} diff --git a/src/main/java/net/sharksystem/asap/ASAPHopImpl.java b/src/main/java/net/sharksystem/asap/ASAPHopImpl.java deleted file mode 100644 index 0252191..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPHopImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.sharksystem.asap; - -public class ASAPHopImpl implements ASAPHop { - private final CharSequence sender; - private final boolean verified; - private final boolean encrypted; - private final ASAPEncounterConnectionType connectionType; - - public ASAPHopImpl(CharSequence sender, boolean verified, boolean encrypted, ASAPEncounterConnectionType connectionType) { - this.sender = sender; - this.verified = verified; - this.encrypted = encrypted; - this.connectionType = connectionType; - } - - @Override - public CharSequence sender() { - return this.sender; - } - - @Override - public ASAPEncounterConnectionType getConnectionType() { - return this.connectionType; - } - - @Override - public boolean verified() { - return this.verified; - } - - @Override - public boolean encrypted() { - return this.encrypted; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("sender: "); - sb.append(this.sender); - sb.append(" | "); - sb.append("verified: "); - sb.append(this.verified); - sb.append(" | "); - sb.append("encrypted: "); - sb.append(this.encrypted); - sb.append(" | "); - sb.append("connectionType: "); - switch (this.connectionType) { - case ONION_NETWORK: sb.append("onionNetwork"); break; - case ASAP_HUB: sb.append("ASAP Hub"); break; - case AD_HOC_LAYER_2_NETWORK: sb.append("Ad-hoc protocol"); break; - case INTERNET: sb.append("Internet"); break; - default: sb.append("unknown"); break; - } - - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPInternalPeerWrapper.java b/src/main/java/net/sharksystem/asap/ASAPInternalPeerWrapper.java deleted file mode 100644 index d3a7eae..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPInternalPeerWrapper.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.engine.ASAPInternalOnlinePeersChangedListener; -import net.sharksystem.asap.engine.ASAPInternalPeer; -import net.sharksystem.asap.protocol.ASAPConnection; -import net.sharksystem.asap.utils.PeerIDHelper; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Set; - -public abstract class ASAPInternalPeerWrapper extends ASAPListenerManagingPeer - implements ASAPInternalOnlinePeersChangedListener { - - private ASAPInternalPeer peer; - - protected void setInternalPeer(ASAPInternalPeer peer) { - this.peer = peer; - this.peer.addOnlinePeersChangedListener(this); - - Log.writeLog(this, "activate online messages on that peer"); - this.peer.activateOnlineMessages(); - } - - - @Override - public boolean isASAPRoutingAllowed(CharSequence applicationFormat) throws IOException, ASAPException { - return this.getInternalPeer().asapRoutingAllowed(applicationFormat); - } - - @Override - public void setASAPRoutingAllowed(CharSequence applicationFormat, boolean allowed) - throws IOException, ASAPException { - - this.getInternalPeer().setAsapRoutingAllowed(applicationFormat, allowed); - } - - protected ASAPInternalPeer getInternalPeer() { - return this.peer; - } - - public CharSequence getPeerID() { - return this.peer.getOwner(); - } - - public boolean samePeer(ASAPPeer otherPeer) { - return this.samePeer(otherPeer.getPeerID()); - } - - public boolean samePeer(CharSequence otherPeerID) { - return PeerIDHelper.sameID(this.getPeerID(), otherPeerID); - } - - @Override - public ASAPStorage getASAPStorage(CharSequence format) throws IOException, ASAPException { - return this.getInternalPeer().getASAPEngine(format); - } - - public ASAPConnection handleConnection(InputStream is, OutputStream os) throws IOException, ASAPException { - return this.peer.handleConnection(is, os); - } - - public ASAPConnection handleConnection(InputStream is, OutputStream os, - ASAPEncounterConnectionType connectionType) throws IOException, ASAPException { - - return this.peer.handleConnection(is, os, connectionType); - } - - public ASAPConnection handleConnection(InputStream is, OutputStream os, boolean encrypt, boolean sign, - ASAPEncounterConnectionType connectionType) throws IOException, ASAPException { - - return this.peer.handleConnection(is, os, encrypt, sign, connectionType, - (Set)null, (Set)null); - } - - public ASAPConnection handleConnection( - InputStream is, OutputStream os, - boolean encrypt, boolean sign, - Set appsWhiteList, Set appsBlackList - ) throws IOException, ASAPException { - return this.peer.handleConnection(is, os, encrypt, sign, appsWhiteList, appsBlackList); - } - - - public ASAPConnection handleConnection(InputStream is, OutputStream os, boolean encrypt, boolean sign, - ASAPEncounterConnectionType connectionType, - Set appsWhiteList, Set appsBlackList) throws IOException, ASAPException { - return this.peer.handleConnection(is, os, encrypt, sign, connectionType, appsWhiteList, appsBlackList); - } - - @Override - public void notifyOnlinePeersChanged(ASAPInternalPeer peer) { - this.notifyOnlinePeersChanged(peer.getOnlinePeers()); - } - - public void notifyOnlinePeersChanged(Set peerList) { - this.environmentChangesListenerManager.notifyListeners(peerList); - } - - - /** - * Make a value persistent with key - * @param key - * @param value - */ - public void putExtra(CharSequence key, byte[] value) throws IOException, ASAPException { - try { - this.peer.putExtra(key, value); - } catch (SharkException e) { - throw new ASAPException(e); - } - } - - /** - * Return a value. Throws an exception if not set - * @param key - * @throws ASAPException key never used in putExtra - */ - public byte[] getExtra(CharSequence key) throws ASAPException, IOException { - try { - return this.peer.getExtra(key); - } catch (SharkException e) { - throw new ASAPException(e); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPListenerManagingPeer.java b/src/main/java/net/sharksystem/asap/ASAPListenerManagingPeer.java deleted file mode 100644 index e71c1ee..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPListenerManagingPeer.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.listenermanager.ASAPChannelContentChangedListenerManager; -import net.sharksystem.asap.listenermanager.ASAPEnvironmentChangesListenerManager; -import net.sharksystem.asap.listenermanager.ASAPMessageReceivedListenerManager; - -public abstract class ASAPListenerManagingPeer implements ASAPPeer { - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAPMessageReceivedListener // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - protected ASAPMessageReceivedListenerManager asapMessageReceivedListenerManager = - new ASAPMessageReceivedListenerManager(); - - public void addASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener) { - this.asapMessageReceivedListenerManager.addASAPMessageReceivedListener(format, listener); - } - - @Override - public void removeASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener) { - this.asapMessageReceivedListenerManager.removeASAPMessageReceivedListener(format, listener); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAPChannelContentChangedListener // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - protected ASAPChannelContentChangedListenerManager asapChannelContentChangedListenerManager = - new ASAPChannelContentChangedListenerManager(); - - @Override - public void addASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener) { - this.asapChannelContentChangedListenerManager.addASAPChannelContentChangedListener(format, listener); - } - - @Override - public void removeASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener) { - this.asapChannelContentChangedListenerManager.removeASAPChannelContentChangedListener(format, listener); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAPEnvironmentChangesListener // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - protected ASAPEnvironmentChangesListenerManager environmentChangesListenerManager = - new ASAPEnvironmentChangesListenerManager(); - - @Override - public void addASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener) { - this.environmentChangesListenerManager.addASAPEnvironmentChangesListener(changesListener); - } - - @Override - public void removeASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener) { - this.environmentChangesListenerManager.removeASAPEnvironmentChangesListener(changesListener); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPMessageCompare.java b/src/main/java/net/sharksystem/asap/ASAPMessageCompare.java deleted file mode 100644 index eb81316..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPMessageCompare.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap; - -public interface ASAPMessageCompare { - /** - * Returns if message A is earlier than message B. This interface must be implemented - * by an applications and is parameter to retrieve a messages iterator object. If set, this - * comparision would define the order on which those messages are delivered. - *

- * Note: It is always assumed that message sent / received in an earlier era are always earlier. - * - * @param messageA - * @param messageB - * @return - */ - boolean earlier(byte[] messageA, byte[] messageB); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListener.java b/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListener.java deleted file mode 100644 index 5b65d15..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.sharksystem.asap; - -import java.io.IOException; -import java.util.List; - -public interface ASAPMessageReceivedListener { - void asapMessagesReceived(ASAPMessages messages, String senderE2E, // E2E part - List asapHops /* Point-to-point part */ ) throws IOException; -} \ No newline at end of file diff --git a/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListenerManagement.java b/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListenerManagement.java deleted file mode 100644 index 5cd1107..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPMessageReceivedListenerManagement.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.sharksystem.asap; - -public interface ASAPMessageReceivedListenerManagement { - /** - * Add a listener that is called when a message came in - * @param format app name == supported format - * @param listener listener object - */ - void addASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener); - void removeASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener); - - /** - * @ return number of listeners - * @return - */ - int getNumberListener(); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPMessageSender.java b/src/main/java/net/sharksystem/asap/ASAPMessageSender.java deleted file mode 100644 index 868f930..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPMessageSender.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.sharksystem.asap; - -import java.io.IOException; - -public interface ASAPMessageSender { - /** - * Send a message - * @param appName - * @param uri - * @param message - * @throws ASAPException - */ - void sendASAPMessage(CharSequence appName, CharSequence uri, - byte[] message) throws ASAPException; - - /** - * When calling this methode, this asap message is sent over any existing connection. - * It is not stored on sender or receiver side. Message listeners are called as usual. Nothing happens (no - * exception is thrown) if there is not a single peer encounter running. - * @param appName - * @param uri - * @param message - * @throws ASAPException - * @throws IOException - */ - void sendTransientASAPMessage(CharSequence appName, CharSequence uri, byte[] message) - throws ASAPException, IOException; - - /** - * When calling this methode, this asap message is sent over any existing connection. - * It is not stored on sender or receiver side. Message listeners are called as usual. Nothing happens (no - * exception is thrown) if there is not a single peer encounter running. - * - * @param nextHopPeerID Peer will try to send a message only to this peer. An ASAPException is thrown if there -* is no running encounter with that peer in place. - * @param appName - * @param uri - * @param message - * @throws ASAPException - * @throws IOException - */ - void sendTransientASAPMessage(CharSequence nextHopPeerID, CharSequence appName, CharSequence uri, byte[] message) - throws ASAPException, IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPMessages.java b/src/main/java/net/sharksystem/asap/ASAPMessages.java deleted file mode 100644 index f2c549f..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPMessages.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalChunk; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -/** - * Chunks are identified by an URI and ordered by era numbers. - * User applications can often define an URI but would hardly like - * to deal with era management. - * - * This interface helps those applications. Classes implementing that - * interface wrap an actual chunk storage and offer a view of an ordered - * list of message. Especially era management is hidden with this interfaces. - * - * It is meant to be a cache. It is *not* assumed that this cache is - * always in sync with the actual chunk storage. Syncing is up to application - * which makes implementing that cache easier. - * - * - * @author thsc - */ -public interface ASAPMessages { - /** - * @return number of messages - */ - int size() throws IOException; - - /** - * @return channel uri - */ - CharSequence getURI(); - - /** - * @return format which - in most cases - matches with an application name - */ - CharSequence getFormat(); - - /** - * - * first, false: newest message comes first - * @return iterator of all messages in that chunk cache - * @throws IOException - * @deprecated this lib works supports byte[] - apps deal with (de)serialization. - */ - Iterator getMessagesAsCharSequence() throws IOException; - - /** - * - * first, false: newest message comes first - * @return iterator of all messages in that chunk cache - * @throws IOException - */ - Iterator getMessages() throws IOException; - - /** - * Returns a message with a given position - * @param position - * @param chronologically in chronological order: true: oldest message comes - * first, false: newest message comes first - * @return message - * @throws ASAPException message on that position does - * not exist - * @throws IOException couldn't read from storage - */ - CharSequence getMessageAsCharSequence(int position, boolean chronologically) - throws ASAPException, IOException; - - byte[] getMessage(int position, boolean chronologically) - throws ASAPException, IOException; - - /** - * Return chunk in which message at position is to be found - * @param position - * @param chronologically - * @return - */ - ASAPChunk getChunk(int position, boolean chronologically) throws IOException, ASAPException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPPeer.java b/src/main/java/net/sharksystem/asap/ASAPPeer.java deleted file mode 100644 index 90352a2..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPPeer.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.fs.ExtraData; - -import java.io.IOException; - -public interface ASAPPeer extends - ASAPMessageSender, - ASAPEnvironmentChangesListenerManagement, - ASAPMessageReceivedListenerManagement, - ASAPChannelContentChangedListenerManagement -{ - CharSequence UNKNOWN_USER = "anon"; - boolean ONLINE_EXCHANGE_DEFAULT = true; - - CharSequence getPeerID(); - - ASAPStorage getASAPStorage(CharSequence format) throws IOException, ASAPException; - - /** - * Provide an ASAP keystore to the peer. Now, point-to-point encryption is possible. - * @param asapKeyStore - */ - void setASAPKeyStore(ASAPKeyStore asapKeyStore); - - /** - * Get ASAP keystore. Throws an exception if not set - * @return ASAP keystore - * @throws ASAPException if no keystore present - */ - ASAPKeyStore getASAPKeyStore() throws ASAPSecurityException; - - /** - * ASAP peer are both: application host and potential router. Routing can be switched on or off. - * We tend to label this behaviour with different ages (stone. bronze, internet), see discussion there. - *

- * If true: This engine will route received messages - * @return - */ - boolean isASAPRoutingAllowed(CharSequence applicationFormat) throws IOException, ASAPException; - - void setASAPRoutingAllowed(CharSequence applicationFormat, boolean allowed) - throws IOException, ASAPException; - - /** - * Returns true if both peer represent the same peer - ID are compared. - * @param otherPeer - * @return - */ - boolean samePeer(ASAPPeer otherPeer); - - boolean samePeer(CharSequence otherPeerID); - - /** - * Handle a connection - * @param is - * @param os - * @param encrypt point-to-point encryption - * @param sign point-to-point signing / verifying ? - * @param connectionType - * @return - * @throws IOException - * @throws ASAPException - */ - /* - ASAPConnection handleConnection(InputStream is, OutputStream os, boolean encrypt, boolean sign, - EncounterConnectionType connectionType) throws IOException, ASAPException; - - - */ - - /** - * Make a value persistent with key - * @param key - * @param value - */ - void putExtra(CharSequence key, byte[] value) throws IOException, ASAPException; - - /** - * Return a value. Throws an exception if not set - * @param key - * @throws ASAPException key never used in putExtra - */ - byte[] getExtra(CharSequence key) throws ASAPException, IOException; - - ExtraData getExtraData() throws SharkException, IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPPeerFS.java b/src/main/java/net/sharksystem/asap/ASAPPeerFS.java deleted file mode 100644 index ba4fe5d..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPPeerFS.java +++ /dev/null @@ -1,189 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.asap.engine.*; -import net.sharksystem.asap.utils.ASAPLogHelper; -import net.sharksystem.fs.ExtraData; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class ASAPPeerFS extends ASAPInternalPeerWrapper implements ASAPPeerService, ASAPChunkAssimilatedListener { - public static final CharSequence DEFAULT_ROOT_FOLDER_NAME = ASAPEngineFS.DEFAULT_ROOT_FOLDER_NAME; - - private final String rootFolder; - private ASAPChunkAssimilatedListener chunkReceivedListener; - - public ASAPPeerFS(CharSequence owner, CharSequence rootFolder, - Collection supportFormats) throws IOException, ASAPException { - super.setInternalPeer(ASAPInternalPeerFS.createASAPPeer(owner, rootFolder, supportFormats, this)); - this.rootFolder = rootFolder.toString(); - } - - public ASAPPeerFS(CharSequence owner, CharSequence rootFolder) throws IOException, ASAPException { - super.setInternalPeer(ASAPInternalPeerFS.createASAPPeer(owner, rootFolder, null, this)); - this.rootFolder = rootFolder.toString(); - } - - public void overwriteChuckReceivedListener(ASAPChunkAssimilatedListener listener) { - Log.writeLogErr(this, this.getPeerID(), "do not use chunk received listener - message received listener is better"); - this.chunkReceivedListener = listener; - } - - private void chunkAssimilated(ASAPMessages receivedMessages, CharSequence format, - CharSequence senderE2E, CharSequence uri, int era, - List asapHopList, boolean callListener) { - - int nrMessages = -1; - try { - nrMessages = receivedMessages.size(); - } catch (IOException e) { - // go ahead - } - - StringBuilder sb = new StringBuilder(); - String hopListString = "hoplist == null"; - if(asapHopList != null) { - int i = 0; - for (ASAPHop hop : asapHopList) { - sb.append("hop#"); - sb.append(i++); - sb.append(": "); - sb.append(hop.toString()); - sb.append("\n"); - } - hopListString = sb.toString(); - } - - sb = new StringBuilder(); - sb.append("\n+++++++++++++++++++++++++++++++++++++++ chunkReceived ++++++++++++++++++++++++++++++++++++++++++++\n"); - sb.append("E2E|P2P: " + senderE2E + " | " + asapHopList.get(asapHopList.size()-1).sender() + " | uri: " + uri); - sb.append(" | era: "); - if(era == ASAP.TRANSIENT_ERA) sb.append("transient"); - else sb.append(era); - sb.append(" | app: " + format); - sb.append(" | #msgs: " + nrMessages); - sb.append("\n"); - sb.append(hopListString); - sb.append("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - Log.writeLog(this, this.getPeerID(), sb.toString()); - - if(callListener) { - // call listener - String numberListeners = "null"; - if(this.asapMessageReceivedListenerManager != null) { - numberListeners = String.valueOf(this.asapMessageReceivedListenerManager.getNumberListener()); - } - - Log.writeLog(this, this.getPeerID(), "notify listeners; number: " + numberListeners); - if (this.asapMessageReceivedListenerManager.getNumberListener() > 0) { - this.asapMessageReceivedListenerManager.notifyReceived( - format, receivedMessages, true, - senderE2E.toString(), asapHopList); - } - - if (this.asapChannelContentChangedListenerManager.getNumberListener() > 0) { - Log.writeLog(this, this.getPeerID(),"notify channel content changed listener"); - this.asapChannelContentChangedListenerManager.notifyChanged(format, uri, era, true); - } - } - } - - @Override - public void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException { - // produce hop list object - - List asapHopList = new ArrayList<>(); - asapHopList.add(asapHop); - this.chunkAssimilated(transientMessages, - transientMessages.getFormat(), asapHop.sender(), transientMessages.getURI(), - ASAP.TRANSIENT_ERA, asapHopList, true); - } - - @Override - public void chunkStored(String format, String senderE2E, String uri, int era, - List asapHopList) throws IOException { - if(this.chunkReceivedListener != null) { - Log.writeLog(this, this.getPeerID(),"chunk received listener set - call this one"); - this.chunkReceivedListener.chunkStored(format, senderE2E, uri, era, asapHopList); - this.chunkAssimilated(null, format, senderE2E, uri, era, asapHopList, false); - } else { - Log.writeLog(this, this.getPeerID(),"extract messages from chunk and notify listener"); - ASAPMessages receivedMessages = - ASAPLogHelper.getMessagesByChunkReceivedInfos(format, senderE2E, uri, this.rootFolder, era); - - this.chunkAssimilated(receivedMessages, format, senderE2E, uri, era, asapHopList, true); - } - } - - /// TODO this method makes absolutely no sense in that class. - @Override - public int getNumberListener() { - return this.asapMessageReceivedListenerManager.getNumberListener(); - } - - // TODO move behaviour control into this package - - @Override - public void sendASAPMessage(CharSequence appName, CharSequence uri, byte[] message) throws ASAPException { - try { - ASAPEngine engine = this.getInternalPeer().createEngineByFormat(appName); - engine.activateOnlineMessages(this.getInternalPeer()); - engine.add(uri, message); - // send online (already done by activating online messages and adding message with engine - /* - try { - this.getInternalPeer().sendOnlineASAPAssimilateMessage(appName, uri, engine.getEra(), message); - } - catch(ASAPException e) { - // no online peers - that's ok - Log.writeLog(this, this.toString(), "could not send message online - that's ok."); - } - */ - } catch (IOException e) { - Log.writeLog(this, this.getPeerID(),e.getLocalizedMessage()); - throw new ASAPException("problems getting asap engine", e); - } - } - - public void sendTransientASAPMessage(CharSequence appName, CharSequence uri, byte[] message) - throws ASAPException, IOException { - - Log.writeLog(this, this.getInternalPeer().getOwner().toString(), - "try sending transient message over existing connections "); - this.getInternalPeer().sendTransientASAPAssimilateMessage(appName, uri, message); - - } - - public void sendTransientASAPMessage(CharSequence nextHopPeerID, - CharSequence appName, CharSequence uri, byte[] message) throws ASAPException, IOException { - - Log.writeLog(this, this.getInternalPeer().getOwner().toString(), - "try sending transient message over existing connections to peerID: " + nextHopPeerID); - this.getInternalPeer().sendTransientASAPAssimilateMessage(appName, uri, nextHopPeerID, message); - } - - public String toString() { - return this.getInternalPeer().getOwner().toString(); - } - - @Override - public void setASAPKeyStore(ASAPKeyStore asapKeyStore) { - this.getInternalPeer().setASAPKeyStore(asapKeyStore); - } - - public ASAPKeyStore getASAPKeyStore() throws ASAPSecurityException { - ASAPKeyStore keyStore = this.getInternalPeer().getASAPKeyStore(); - if(keyStore == null) throw new ASAPSecurityException("no keystore set"); - return keyStore; - } - - @Override - public ExtraData getExtraData() throws SharkException, IOException { - return this.getInternalPeer().getExtraData(); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPPeerService.java b/src/main/java/net/sharksystem/asap/ASAPPeerService.java deleted file mode 100644 index e1e40de..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPPeerService.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.asap.engine.ASAPChunkAssimilatedListener; - -public interface ASAPPeerService extends ASAPPeer, ASAPConnectionHandler { - // long DEFAULT_MAX_PROCESSING_TIME = 30000; // 30 seconds - long DEFAULT_MAX_PROCESSING_TIME = Long.MAX_VALUE; // eternity - debugging setting - - /** - * Overwrite internal listener. This method is used e.g. in Androiud on service side. The asap peer is informed - * about newly received chunks. That news is broadcasted to application side which performs the actual processing. - * - * @param listener this listener is called instead - no further chunk processing is made by this object. - */ - void overwriteChuckReceivedListener(ASAPChunkAssimilatedListener listener); -} diff --git a/src/main/java/net/sharksystem/asap/ASAPSecurityException.java b/src/main/java/net/sharksystem/asap/ASAPSecurityException.java deleted file mode 100644 index b66d7dd..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPSecurityException.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap; - -public class ASAPSecurityException extends ASAPException { - public ASAPSecurityException() { - super(); - } - public ASAPSecurityException(Throwable cause) { - super(cause); - } - public ASAPSecurityException(String message) { - super(message); - } - public ASAPSecurityException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/net/sharksystem/asap/ASAPStorage.java b/src/main/java/net/sharksystem/asap/ASAPStorage.java deleted file mode 100644 index a372f22..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPStorage.java +++ /dev/null @@ -1,154 +0,0 @@ -package net.sharksystem.asap; - -import java.io.IOException; -import java.util.List; - -public interface ASAPStorage { - /** - * Get owner id/name of this storage. It is the name of the local peer. - * @return owner id/name - */ - CharSequence getOwner(); - - /** - * @return list of peers with an incoming storage - * @see #getExistingIncomingStorage(CharSequence) - */ - List getSender(); - - /** - * Peer exchange message during an encounter. Received messages are stored in - * an incoming storage - * @param sender - * @return storage with received messages from a peer - * @throws IOException - * @throws ASAPException - */ - ASAPStorage getExistingIncomingStorage(CharSequence sender) throws IOException, ASAPException; - - /** - * Get storage - parameter decides if to create a non-existing storage - * @param sender - * @param create - * @return - * @throws IOException - * @throws ASAPException - */ - ASAPStorage getIncomingStorage(CharSequence sender, boolean create) throws IOException, ASAPException; - - /** - * Get storage - create of required - * @param sender - * @return - * @throws IOException - * @throws ASAPException - */ - ASAPStorage getIncomingStorage(CharSequence sender) throws IOException, ASAPException; - /** - * - * @return storage format / app - */ - CharSequence getFormat(); - - /** - * - * @return list of channel uris present in this storage - * @throws IOException - */ - List getChannelURIs() throws IOException; - - /** - * Create a channel that includes all messages (send or received) with this uri. - * @param uri - * @return channel containing all message issued by owner of this storage. Received messages are not part - * of this channel. (See makan implementation) - * @throws ASAPException if no channel with that uri exists in this storage - */ - ASAPChannel getChannel(CharSequence uri) throws ASAPException, IOException; - - /** - * - * @param uri channel uri - * @return if channel exists - in other words: at least one message was added with this channel uri - */ - boolean channelExists(CharSequence uri) throws IOException; - - /** - * Get oldest era available on that peer. - * @return - */ - public int getOldestEra(); - - /** - * Get current era. - * @return - */ - public int getEra(); - - /** - * Get next era number. Era numbers are organized in a circle. Number 0 - * follows Integer.MAXVALUE. That method takes care of that fact. - * No change is made on current era. - * - * @param era - * @return - */ - public int getNextEra(int era); - - /** - * Get previous era number. Era numbers are organized in a circle. Er - * number 0 is proceeded by era number Integer.MAXVALUE. - * That method takes care of that fact. - * No change is made on current era. - * - * @param era - * @return - */ - int getPreviousEra(int era); - - /** - * - * @return The local chunk storage that is meant to be used by the local - * app. Note: That storage is changed during an ASAP session. - */ - ASAPChunkStorage getChunkStorage(); - - void createChannel(CharSequence urlTarget) throws IOException, ASAPException; - - void removeChannel(CharSequence uri) throws IOException; - /** - * - * @param uri - * @param messageAsBytes - * @throws IOException - * @see ASAPChannel#addMessage(byte[]) - */ - void add(CharSequence uri, byte[] messageAsBytes) throws IOException; - - /** - * Put some extra information on that channel - * @param uri describing the channel - * @param key - * @param value - * @throws IOException - */ - void putExtra(CharSequence uri, String key, String value) throws IOException; - - /** - * Remove a string from extra information set - * @param uri - * @param key - * @return - * @throws IOException - */ - CharSequence removeExtra(CharSequence uri, String key) throws IOException; - - /** - * Get a string from extra information set without removing - * @param uri - * @param key - * @return - * @throws IOException - */ - CharSequence getExtra(CharSequence uri, String key) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/ASAPUtils.java b/src/main/java/net/sharksystem/asap/ASAPUtils.java deleted file mode 100644 index 26b00ce..0000000 --- a/src/main/java/net/sharksystem/asap/ASAPUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.sharksystem.asap; - -import net.sharksystem.utils.Log; - -import java.util.ArrayList; -import java.util.Collection; - -public class ASAPUtils { - /** - * - * @param searchSpace list of possible eras - * @param fromEra lowest era - * @param toEra highest era - * @return list of era which are within from and to and also in search space - */ - public static Collection getErasInRange(Collection searchSpace, - int fromEra, int toEra) { - - Collection eras = new ArrayList<>(); - - // the only trick is to be aware of the cyclic nature of era numbers - boolean wrapped = fromEra > toEra; // it reached the era end and started new - - for(Integer era : searchSpace) { - if(!wrapped) { - //INIT ---- from-> +++++++++++++ <-to ----- MAX (+ fits) - if(era >= fromEra && era <= toEra) eras.add(era); - } else { - // INIT+++++++++<-to ------ from->++++++MAX - if(era <= toEra && era >= ASAP.INITIAL_ERA - || era >= fromEra && era <= ASAP.MAX_ERA - ) eras.add(era); - } - } - - return eras; - - } -} diff --git a/src/main/java/net/sharksystem/asap/apps/TCPServerSocketAcceptor.java b/src/main/java/net/sharksystem/asap/apps/TCPServerSocketAcceptor.java deleted file mode 100644 index 8703b34..0000000 --- a/src/main/java/net/sharksystem/asap/apps/TCPServerSocketAcceptor.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.sharksystem.asap.apps; - -import net.sharksystem.asap.ASAPEncounterManager; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.utils.Log; -import net.sharksystem.utils.streams.StreamPair; -import net.sharksystem.utils.tcp.SocketFactory; -import net.sharksystem.utils.tcp.StreamPairCreatedListener; - -import java.io.IOException; - -public class TCPServerSocketAcceptor implements StreamPairCreatedListener { - private final ASAPEncounterManager encounterManager; - private final SocketFactory socketFactory; - - public TCPServerSocketAcceptor(int portNumber, ASAPEncounterManager encounterManager, boolean remainOpen) - throws IOException { - this.encounterManager = encounterManager; - this.socketFactory = new SocketFactory(portNumber, this, remainOpen); - - Log.writeLog(this, "start socket factory - no race condition assumed"); - new Thread(socketFactory).start(); - } - - public TCPServerSocketAcceptor(int portNumber, ASAPEncounterManager encounterManager) throws IOException { - this(portNumber, encounterManager, false); - } - - public void close() throws IOException { - this.socketFactory.close(); - } - - @Override - public void streamPairCreated(StreamPair streamPair) { - Log.writeLog(this, "new stream pair created"); - try { - this.encounterManager.handleEncounter(streamPair, ASAPEncounterConnectionType.INTERNET); - } catch (IOException e) { - Log.writeLogErr(this, "exception when asking for new connection handling: " - + e.getLocalizedMessage()); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/apps/gossip/GossipUI.java b/src/main/java/net/sharksystem/asap/apps/gossip/GossipUI.java deleted file mode 100644 index 4b386aa..0000000 --- a/src/main/java/net/sharksystem/asap/apps/gossip/GossipUI.java +++ /dev/null @@ -1,164 +0,0 @@ -package net.sharksystem.asap.apps.gossip; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.engine.*; -import net.sharksystem.asap.utils.ASAPLogHelper; -import net.sharksystem.asap.cmdline.TCPStream; -import net.sharksystem.asap.cmdline.TCPStreamCreatedListener; -import net.sharksystem.utils.Log; -import net.sharksystem.utils.SerializationHelper; - -import java.io.IOException; -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -// java -cp ASAP_Engine_x.y.z.jar net.sharksystem.asap.apps.gossip.GossipUI Alice 7070 7071 -public class GossipUI implements ASAPChunkAssimilatedListener { - private List remotePortNumber; - private String peerName; - private int portnumber; - private ASAPInternalPeer asapInternalPeer; - private String rootFolderName; - - public GossipUI(String peerName, int portnumber, List portnumberlist) { - this.peerName = peerName; - this.portnumber = portnumber; - this.remotePortNumber = portnumberlist; - - Log.writeLog(this, "start peer " + this.peerName); - Log.writeLog(this, "local port " + this.portnumber); - Log.writeLog(this, "try to connect to ports " + this.remotePortNumber); - } - - public static void main(String args[]) throws InterruptedException { - if(args.length < 3) { - Log.writeLogErr(GossipUI.class, "Peer name, local port and least one port required to establish a network"); - System.exit(0); - } - - // parse and set up - String peerName = args[0]; - int portnumber = Integer.parseInt(args[1]); - List portnumberlist = new ArrayList<>(); - for(int i = 2; i < args.length; i++) { - portnumberlist.add(Integer.parseInt(args[i])); - } - - GossipUI gossip = new GossipUI(peerName, portnumber, portnumberlist); - - gossip.go(); - - // wait forever - Thread.sleep(10000); - } - - private void println(String msg) { - Log.writeLog(this, "///////////////////////////////////////////////////"); - Log.writeLog(this, "Example: " + msg); - Log.writeLog(this, "///////////////////////////////////////////////////"); - } - - private void go() { - try { - this.println("set up system"); - this.rootFolderName = this.peerName; - this.asapInternalPeer = ASAPInternalPeerFS.createASAPPeer(this.peerName, - this.rootFolderName, ASAPInternalPeer.DEFAULT_MAX_PROCESSING_TIME, this); - - this.println("create engine"); - ASAPEngine exampleApp = asapInternalPeer.createEngineByFormat("exampleApp"); - - DateFormat df = DateFormat.getInstance(); - String myMessage = "message from " + this.peerName + " at " + df.format(new Date()); - - // convert to bytes - byte[] byteMessage = SerializationHelper.str2bytes(myMessage); - this.println("add message"); - exampleApp.add("exampleChannel", byteMessage); - - this.println("open tcp server port"); - // try to establish connections - new ASAPConnectionCreator(new TCPStream(this.portnumber, true, - "server port: " + this.peerName)); - - this.println("try to connect others"); - for(int port : this.remotePortNumber) { - new ASAPConnectionCreator(port); - } - - } catch (ASAPException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void chunkStored(String format, String senderE2E, String uri, int era, - List asapHop) throws IOException { - - ASAPMessages receivedMessages = - ASAPLogHelper.getMessagesByChunkReceivedInfos(format, senderE2E, uri, this.rootFolderName, era); - - this.println("messages received: " + format + " | " + senderE2E + " | " + uri); - - Iterator messages = receivedMessages.getMessages(); - while(messages.hasNext()) { - byte[] msgBytes = messages.next(); - String receivedMessage = SerializationHelper.bytes2str(msgBytes); - this.println("message received: " + receivedMessage); - }; - } - - private void printReceivedMessages(ASAPMessages asapMessages, List asapHop) throws IOException { - this.println("messages received: " + asapMessages.getFormat() + " | " + asapMessages.getURI()); - - Iterator messages = asapMessages.getMessages(); - while(messages.hasNext()) { - byte[] msgBytes = messages.next(); - String receivedMessage = SerializationHelper.bytes2str(msgBytes); - this.println("message received: " + receivedMessage); - }; - } - - public void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException { - this.printReceivedMessages(transientMessages, null); - } - - private class ASAPConnectionCreator extends Thread implements TCPStreamCreatedListener { - private TCPStream tcpStream; - - ASAPConnectionCreator(int port) { - this(new TCPStream(port, false, "connect to " + String.valueOf(port))); - } - - ASAPConnectionCreator(TCPStream tcpStream) { - this.tcpStream = tcpStream; - this.tcpStream.setListener(ASAPConnectionCreator.this); - this.start(); - } - - public void run() { - try { - this.tcpStream.start(); - this.tcpStream.waitForConnection(Long.MAX_VALUE); - } catch (IOException e) { - println("wait for connection killed. "); - } - } - - @Override - public void streamCreated(TCPStream channel) { - try { - GossipUI.this.asapInternalPeer.handleConnection(channel.getInputStream(), channel.getOutputStream()); - } catch (Exception e) { - GossipUI.this.println("exception caught: " + e.getLocalizedMessage()); - } - } - } -} diff --git a/src/main/java/net/sharksystem/asap/apps/testsupport/ASAPTestPeerFS.java b/src/main/java/net/sharksystem/asap/apps/testsupport/ASAPTestPeerFS.java deleted file mode 100644 index a7be174..0000000 --- a/src/main/java/net/sharksystem/asap/apps/testsupport/ASAPTestPeerFS.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.sharksystem.asap.apps.testsupport; - -import net.sharksystem.asap.ASAPPeerFS; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.testhelper.ASAPTesthelper; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Collection; - -public class ASAPTestPeerFS extends ASAPPeerFS { - private ServerSocket serverSocket = null; - private Socket socket = null; - - public ASAPTestPeerFS(CharSequence peerName, Collection supportedFormats) throws IOException, ASAPException { - this(peerName, "./testPeerFS/" + peerName, supportedFormats); - } - - public ASAPTestPeerFS(CharSequence peerName, CharSequence rootFolder, Collection supportedFormats) - throws IOException, ASAPException { - super(peerName, rootFolder, supportedFormats); - } - - public void startEncounter(int port, ASAPTestPeerFS otherPeer) throws IOException { - this.serverSocket = new ServerSocket(port); - - new Thread(new Runnable() { - @Override - public void run() { - try { - ASAPTestPeerFS.this.socket = ASAPTestPeerFS.this.serverSocket.accept(); - } catch (IOException e) { - Log.writeLog(ASAPTestPeerFS.this,"fatal while waiting for client to connect: " - + e.getLocalizedMessage()); - } - - ASAPTestPeerFS.this.startSession(); - } - }).start(); - - // wait a moment - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } - - otherPeer.connect(port); - } - - private void connect(int port) throws IOException { - this.socket = new Socket("localhost", port); - this.startSession(); - } - - public void stopEncounter(ASAPTestPeerFS otherPeer) throws IOException { - this.socket.close(); - } - - private void startSession() { - new Thread(new Runnable() { - @Override - public void run() { - try { - ASAPTestPeerFS.this.handleConnection( - ASAPTestPeerFS.this.socket.getInputStream(), - ASAPTestPeerFS.this.socket.getOutputStream(), - ASAPEncounterConnectionType.INTERNET); - } catch (IOException | ASAPException e) { - Log.writeLog(ASAPTestPeerFS.this,"fatal while connecting: " + e.getLocalizedMessage()); - } - } - }).start(); - } -} diff --git a/src/main/java/net/sharksystem/asap/apps/testsupport/TestASAPConnectionHandler.java b/src/main/java/net/sharksystem/asap/apps/testsupport/TestASAPConnectionHandler.java deleted file mode 100644 index d850afa..0000000 --- a/src/main/java/net/sharksystem/asap/apps/testsupport/TestASAPConnectionHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.sharksystem.asap.apps.testsupport; - -import net.sharksystem.asap.ASAPConnectionHandler; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.protocol.ASAPConnection; -import net.sharksystem.asap.protocol.ASAPConnectionListener; -import net.sharksystem.asap.protocol.ASAPOnlineMessageSource; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Set; - -public class TestASAPConnectionHandler implements ASAPConnectionHandler { - @Override - public ASAPConnection handleConnection(InputStream is, OutputStream os, boolean encrypt, boolean sign, Set appsWhiteList, Set appsBlackList) throws IOException, ASAPException { - return this.dummyHandleConnection(); - } - - @Override - public ASAPConnection handleConnection(InputStream is, OutputStream os, boolean encrypt, boolean sign, ASAPEncounterConnectionType connectionType, Set appsWhiteList, Set appsBlackList) throws IOException, ASAPException { - return this.dummyHandleConnection(); - } - - @Override - public ASAPConnection handleConnection(InputStream is, OutputStream os) throws IOException, ASAPException { - return this.dummyHandleConnection(); - } - - @Override - public ASAPConnection handleConnection(InputStream inputStream, OutputStream outputStream, ASAPEncounterConnectionType connectionType) throws IOException, ASAPException { - return this.dummyHandleConnection(); - } - - private ASAPConnection dummyHandleConnection() { - Log.writeLog(this, "handleConnection"); - return new ASAPConnection() { - @Override - public CharSequence getEncounteredPeer() { - return "dummy"; - } - - @Override - public void addOnlineMessageSource(ASAPOnlineMessageSource source) { - - } - - @Override - public void removeOnlineMessageSource(ASAPOnlineMessageSource source) { - - } - - @Override - public void addASAPConnectionListener(ASAPConnectionListener asapConnectionListener) { - - } - - @Override - public void removeASAPConnectionListener(ASAPConnectionListener asapConnectionListener) { - - } - - @Override - public boolean isSigned() { - return false; - } - - @Override - public ASAPEncounterConnectionType getASAPEncounterConnectionType() { - return ASAPEncounterConnectionType.UNKNOWN; - } - - @Override - public void kill() { - - } - }; - } -} diff --git a/src/main/java/net/sharksystem/asap/cmdline/CmdLineUI.java b/src/main/java/net/sharksystem/asap/cmdline/CmdLineUI.java deleted file mode 100644 index 5bdeb27..0000000 --- a/src/main/java/net/sharksystem/asap/cmdline/CmdLineUI.java +++ /dev/null @@ -1,782 +0,0 @@ -package net.sharksystem.asap.cmdline; - -import net.sharksystem.asap.ASAPChannel; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalStorage; -import net.sharksystem.asap.engine.*; -import net.sharksystem.fs.FSUtils; - -import java.io.*; -import java.util.*; - -/** - * @author thsc - */ -public class CmdLineUI { - // commands - public static final String CONNECT = "connect"; - public static final String OPEN = "open"; - public static final String EXIT = "exit"; - public static final String LIST = "list"; - public static final String KILL = "kill"; - public static final String SETWAITING = "setwaiting"; - public static final String CREATE_ASAP_PEER = "newpeer"; - public static final String CREATE_ASAP_APP = "newapp"; - public static final String CREATE_ASAP_CHANNEL = "newchannel"; - public static final String CREATE_ASAP_MESSAGE = "newmessage"; - public static final String RESET_ASAP_STORAGES = "resetstorage"; - public static final String SET_SEND_RECEIVED_MESSAGES = "setSendReceived"; - public static final String PRINT_CHANNEL_INFORMATION = "printChannelInfo"; - public static final String PRINT_STORAGE_INFORMATION = "printStorageInfo"; - public static final String PRINT_ALL_INFORMATION = "printAll"; - public static final String SLEEP = "sleep"; - public static final String SHOW_LOG = "showlog"; - - private PrintStream standardOut = System.out; - private PrintStream standardError = System.err; - - private BufferedReader userInput; - - public static final String PEERS_ROOT_FOLDER = "asapPeers"; - private Map peers = new HashMap(); - - public static void main(String[] args) throws IOException, ASAPException { - PrintStream os = System.out; - - os.println("Welcome SN2 version 0.1"); - CmdLineUI userCmd = new CmdLineUI(os, System.in); - - userCmd.printUsage(); - userCmd.runCommandLoop(); - } - - public CmdLineUI(PrintStream out) throws IOException, ASAPException { - this(out, null); - } - - public void setOutStreams(PrintStream ps) { - this.standardOut = ps; - this.standardError = ps; - } - - /** - * only for batch processing - removes anything from the past - * @throws IOException - * @throws ASAPException - */ - public CmdLineUI() { - this.doResetASAPStorages(); - } - - public CmdLineUI(PrintStream os, InputStream is) throws IOException, ASAPException { - this.standardOut = os; - this.userInput = is != null ? new BufferedReader(new InputStreamReader(is)) : null; - - // set up peers - File rootFolder = new File(PEERS_ROOT_FOLDER); - if(rootFolder.exists()) { - // each root folder is a peer - per definition in this very application - String[] peerNames = rootFolder.list(); - - // set up peers - for(String peerName : peerNames) { - this.createPeer(peerName); - } - } - } - - public void printUsage() { - StringBuilder b = new StringBuilder(); - - b.append("\n"); - b.append("\n"); - b.append("valid commands:"); - b.append("\n"); - b.append(CONNECT); - b.append(".. connect to remote engine"); - b.append("\n"); - b.append(OPEN); - b.append(".. open socket"); - b.append("\n"); - b.append(LIST); - b.append(".. list open connections"); - b.append("\n"); - b.append(KILL); - b.append(".. kill an open connection"); - b.append("\n"); - b.append(SETWAITING); - b.append(".. set waiting period"); - b.append("\n"); - b.append(CREATE_ASAP_PEER); - b.append(".. create new asap peer"); - b.append("\n"); - b.append(CREATE_ASAP_APP); - b.append(".. create new asap app (==engine)"); - b.append("\n"); - b.append(CREATE_ASAP_CHANNEL); - b.append(".. create new closed asap channel"); - b.append("\n"); - b.append(CREATE_ASAP_MESSAGE); - b.append(".. add message to engine"); - b.append("\n"); - b.append(RESET_ASAP_STORAGES); - b.append(".. removes all asap engines"); - b.append("\n"); - b.append(SET_SEND_RECEIVED_MESSAGES); - b.append(".. set whether received message are to be sent"); - b.append("\n"); - b.append(PRINT_ALL_INFORMATION); - b.append(".. print general information of peers"); - b.append("\n"); - b.append(PRINT_STORAGE_INFORMATION); - b.append(".. print general information about a storage"); - b.append("\n"); - b.append(PRINT_CHANNEL_INFORMATION); - b.append(".. print general information about a channel"); - b.append("\n"); - b.append(SLEEP); - b.append(".. sleep some milliseconds - helps writing batch programs"); - b.append("\n"); - b.append(SHOW_LOG); - b.append(".. print log of entered commands of this session"); - b.append("\n"); - b.append(EXIT); - b.append(".. exit"); - - this.standardOut.println(b.toString()); - } - - public void printUsage(String cmdString, String comment) throws ASAPException { - PrintStream out = this.standardOut; - - if(comment == null) comment = " "; - out.println("malformed command: " + comment); - out.println("use:"); - switch(cmdString) { - case CONNECT: - out.println(CONNECT + " [IP/DNS-Name_remoteHost] remotePort localEngineName"); - out.println("omitting remote host: localhost is assumed"); - out.println("example: " + CONNECT + " localhost 7070 Bob"); - out.println("example: " + CONNECT + " 7070 Bob"); - out.println("in both cases try to connect to localhost:7070 and let engine Bob handle " + - "connection when established"); - break; - case OPEN: - out.println(OPEN + " localPort engineName"); - out.println("example: " + OPEN + " 7070 Alice"); - out.println("opens a server socket #7070 and let engine Alice handle connection when established"); - break; - case LIST: - out.println("lists all open connections / client and server"); - break; - case KILL: - out.println(KILL + " channel name"); - out.println("example: " + KILL + " localhost:7070"); - out.println("kills channel named localhost:7070"); - out.println("channel names are produced by using list"); - out.println(KILL + " all .. kills all open connections"); - break; - case SETWAITING: - out.println(SETWAITING + " number of millis to wait between two connection attempts"); - out.println("example: " + KILL + " 1000"); - out.println("set waiting period to one second"); - break; - case CREATE_ASAP_PEER: - out.println(CREATE_ASAP_PEER + " name"); - out.println("example: " + CREATE_ASAP_PEER + " Alice"); - out.println("create peer called Alice - data kept under a folder called " - + PEERS_ROOT_FOLDER + "/Alice"); - break; - case CREATE_ASAP_APP: - out.println(CREATE_ASAP_APP + " peername appName"); - out.println("example: " + CREATE_ASAP_APP + " Alice chat"); - break; - case CREATE_ASAP_CHANNEL: - out.println(CREATE_ASAP_CHANNEL + " peername appName uri (recipient)+"); - out.println("example: " + CREATE_ASAP_CHANNEL + " Alice chat sn2://abChat Bob Clara"); - break; - case CREATE_ASAP_MESSAGE: - out.println(CREATE_ASAP_MESSAGE + " peername appName uri message"); - out.println("example: " + CREATE_ASAP_MESSAGE + " Alice chat sn2://abChat HiBob"); - out.println("note: message can only be ONE string. That would not work:"); - out.println("does not work: " + CREATE_ASAP_MESSAGE + " Alice chat sn2://abChat Hi Bob"); - out.println("five parameters instead of four."); - break; - case RESET_ASAP_STORAGES: - out.println(RESET_ASAP_STORAGES); - out.println("removes all storages"); - break; - case SET_SEND_RECEIVED_MESSAGES: - out.println(SET_SEND_RECEIVED_MESSAGES + " storageName [on | off]"); - out.println("set whether send received messages"); - out.println("example: " + SET_SEND_RECEIVED_MESSAGES + " Alice:chat on"); - break; - case PRINT_CHANNEL_INFORMATION: - out.println(PRINT_CHANNEL_INFORMATION + " peername appName uri"); - out.println("example: " + PRINT_CHANNEL_INFORMATION + " Alice chat sn2://abChat"); - break; - case PRINT_STORAGE_INFORMATION: - out.println(PRINT_STORAGE_INFORMATION + " peername appName"); - out.println("example: " + PRINT_STORAGE_INFORMATION + " Alice chat"); - break; - case PRINT_ALL_INFORMATION: - out.println(PRINT_ALL_INFORMATION); - break; - case SLEEP: - out.println(SLEEP + " milliseconds"); - out.println("example: " + SLEEP + " sleep 1000"); - out.println("process sleeps a second == 1000 ms"); - break; - case SHOW_LOG: - out.println(SHOW_LOG); - break; - default: - out.println("unknown command: " + cmdString); - } - throw new ASAPException("had to print usage"); - } - - private List cmds = new ArrayList<>(); - - public void runCommandLoop(PrintStream os, InputStream is) { - this.standardOut = os; - this.userInput = is != null ? new BufferedReader(new InputStreamReader(is)) : null; - - this.runCommandLoop(); - } - - public void runCommandLoop() { - boolean again = true; - - while(again) { - boolean rememberCommand = true; - String cmdLineString = null; - - try { - // read user input - cmdLineString = userInput.readLine(); - - // finish that loop if less than nothing came in - if(cmdLineString == null) break; - - // trim whitespaces on both sides - cmdLineString = cmdLineString.trim(); - - // extract command - int spaceIndex = cmdLineString.indexOf(' '); - spaceIndex = spaceIndex != -1 ? spaceIndex : cmdLineString.length(); - - // got command string - String commandString = cmdLineString.substring(0, spaceIndex); - - // extract parameters string - can be empty - String parameterString = cmdLineString.substring(spaceIndex); - parameterString = parameterString.trim(); - - // start command loop - switch(commandString) { - case CONNECT: - this.doConnect(parameterString); break; - case OPEN: - this.doOpen(parameterString); break; - case LIST: - this.doList(); break; - case KILL: - this.doKill(parameterString); break; - case SETWAITING: - this.doSetWaiting(parameterString); break; - case CREATE_ASAP_PEER: - this.doCreateASAPPeer(parameterString); break; - case CREATE_ASAP_APP: // same - this.doCreateASAPApp(parameterString); break; - case CREATE_ASAP_CHANNEL: - this.doCreateASAPChannel(parameterString); break; - case CREATE_ASAP_MESSAGE: - this.doCreateASAPMessage(parameterString); break; - case RESET_ASAP_STORAGES: - this.doResetASAPStorages(); break; - case SET_SEND_RECEIVED_MESSAGES: - this.doSetSendReceivedMessage(parameterString); break; - case PRINT_CHANNEL_INFORMATION: - this.doPrintChannelInformation(parameterString); break; - case PRINT_STORAGE_INFORMATION: - this.doPrintStorageInformation(parameterString); break; - case SLEEP: - this.doSleep(parameterString); break; - case SHOW_LOG: - this.doShowLog(); rememberCommand = false; break; - case PRINT_ALL_INFORMATION: - this.doPrintAllInformation(); break; - case "q": // convenience - case EXIT: - this.doKill("all"); - again = false; break; // end loop - - default: this.standardError.println("unknown command:" + cmdLineString); - this.printUsage(); - rememberCommand = false; - break; - } - } catch (ASAPException ex) { - rememberCommand = false; - } catch (IOException ex) { - this.standardOut.println("cannot read from input stream"); - System.exit(0); - } - - if(rememberCommand) { - this.cmds.add(cmdLineString); - } - } - } - - private Map streams = new HashMap<>(); - private long waitPeriod = 1000*30; // 30 seconds - - private void setWaitPeriod(long period) { - this.waitPeriod = period; - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAP API usage // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - private void createPeer(String name) throws IOException, ASAPException { - ExampleASAPChunkReceivedListener asapChunkReceivedListener = - new ExampleASAPChunkReceivedListener(PEERS_ROOT_FOLDER + "/" + name); - - ASAPInternalPeer asapInternalPeer = ASAPInternalPeerFS.createASAPPeer(name, // peer name - PEERS_ROOT_FOLDER + "/" + name, // peer folder - asapChunkReceivedListener); - - this.peers.put(name, asapInternalPeer); - } - - private ASAPEngine getEngine(String peername, String appName) throws ASAPException, IOException { - ASAPInternalPeer asapInternalPeer = this.peers.get(peername); - if(asapInternalPeer == null) { - throw new ASAPException("peer does not exist: " + peername); - } - - return asapInternalPeer.getEngineByFormat(appName); - } - - public ASAPInternalPeer getASAPPeer(String peerName) throws ASAPException { - ASAPInternalPeer asapInternalPeer = this.peers.get(peerName); - if(asapInternalPeer == null) { - throw new ASAPException("engine does not exist: " + peerName); - } - - return asapInternalPeer; - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // attach layer 2 (ad-hoc) protocol to ASAP // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private void startTCPStream(String name, TCPStream stream, String peerName) throws ASAPException { - stream.setWaitPeriod(this.waitPeriod); - ASAPInternalPeer asapInternalPeer = this.getASAPPeer(peerName); - - stream.setListener(new TCPStreamCreatedHandler(asapInternalPeer)); - stream.start(); - this.streams.put(name, stream); - } - - private class TCPStreamCreatedHandler implements TCPStreamCreatedListener { - private final ASAPInternalPeer asapInternalPeer; - - public TCPStreamCreatedHandler(ASAPInternalPeer asapInternalPeer) { - this.asapInternalPeer = asapInternalPeer; - } - - @Override - public void streamCreated(TCPStream channel) { - CmdLineUI.this.standardOut.println("Channel created"); - - try { - this.asapInternalPeer.handleConnection( - channel.getInputStream(), - channel.getOutputStream()); - } catch (IOException | ASAPException e) { - CmdLineUI.this.standardOut.println("call of engine.handleConnection failed: " - + e.getLocalizedMessage()); - } - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // method implementations // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - public void doConnect(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String remoteHost = st.nextToken(); - String remotePortString = st.nextToken(); - String engineName = null; - if(!st.hasMoreTokens()) { - // no remote host set - shift - engineName = remotePortString; - remotePortString = remoteHost; - remoteHost = "localhost"; - } else { - engineName = st.nextToken(); - } - int remotePort = Integer.parseInt(remotePortString); - - String name = remoteHost + ":" + remotePortString; - - this.startTCPStream(name, new TCPStream(remotePort, false, name), engineName); - } - catch(RuntimeException re) { - this.printUsage(CONNECT, re.getLocalizedMessage()); - } catch (ASAPException e) { - this.printUsage(CONNECT, e.getLocalizedMessage()); - } - } - - public void doOpen(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String portString = st.nextToken(); - String engineName = st.nextToken(); - - int port = Integer.parseInt(portString); - String name = "server:" + port; - - this.startTCPStream(name, new TCPStream(port, true, name), engineName); - } - catch(RuntimeException re) { - this.printUsage(OPEN, re.getLocalizedMessage()); - } catch (ASAPException e) { - this.printUsage(OPEN, e.getLocalizedMessage()); - } - } - - public void doList() throws ASAPException { - this.standardOut.println("connections:"); - for(String connectionName : this.streams.keySet()) { - this.standardOut.println(connectionName); - } - - this.doPrintAllInformation(); - } - - public void doKill(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String channelName = st.nextToken(); - if(channelName.equalsIgnoreCase("all")) { - this.standardOut.println("kill all open channels.."); - for(TCPStream channel : this.streams.values()) { - channel.kill(); - } - this.streams = new HashMap<>(); - this.standardOut.println(".. done"); - } else { - - TCPStream channel = this.streams.remove(channelName); - if (channel == null) { - this.standardError.println("channel does not exist: " + channelName); - return; - } - this.standardOut.println("kill channel"); - channel.kill(); - - this.standardOut.println(".. done"); - } - } - catch(RuntimeException e) { - this.printUsage(KILL, e.getLocalizedMessage()); - } - } - - public void doSetWaiting(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String waitingPeriodString = st.nextToken(); - long period = Long.parseLong(waitingPeriodString); - this.setWaitPeriod(period); - } - catch(RuntimeException e) { - this.printUsage(SETWAITING, e.getLocalizedMessage()); - } - } - - public void doCreateASAPPeer(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peerName = st.nextToken(); - this.createPeer(peerName); - } - catch(RuntimeException e) { - this.printUsage(CREATE_ASAP_PEER, e.getLocalizedMessage()); - } catch (IOException | ASAPException e) { - this.printUsage(CREATE_ASAP_PEER, e.getLocalizedMessage()); - } - } - - public void doCreateASAPApp(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peer = st.nextToken(); - String appName = st.nextToken(); - - ASAPInternalPeer asapInternalPeer = this.peers.get(peer); - if(asapInternalPeer != null) { - ASAPInternalStorage storage = asapInternalPeer.createEngineByFormat(appName); - /* - if(!storage.isASAPManagementStorageSet()) { - storage.setASAPManagementStorage(ASAPEngineFS.getASAPStorage(peer, - PEERS_ROOT_FOLDER + "/" + peer + "/ASAPManagement", - ASAP_1_0.ASAP_MANAGEMENT_FORMAT)); - }*/ - } - } - catch(RuntimeException e) { - this.printUsage(CREATE_ASAP_APP, e.getLocalizedMessage()); - } catch (IOException | ASAPException e) { - this.printUsage(CREATE_ASAP_APP, e.getLocalizedMessage()); - } - } - - public void doCreateASAPChannel(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peername = st.nextToken(); - String appName = st.nextToken(); - String uri = st.nextToken(); - - ASAPInternalStorage storage = this.getEngine(peername, appName); - - Set recipients = new HashSet<>(); - - // one recipient is mandatory - provoke an exception otherwise - recipients.add(st.nextToken()); - - // optional recipients - while(st.hasMoreTokens()) { - recipients.add(st.nextToken()); - } - - // finally add peername - recipients.add(peername); - - storage.createChannel(peername, uri, recipients); - } - catch(RuntimeException e) { - this.printUsage(CREATE_ASAP_CHANNEL, e.getLocalizedMessage()); - } catch (IOException | ASAPException e) { - this.printUsage(CREATE_ASAP_CHANNEL, e.getLocalizedMessage()); - } - } - - public void doCreateASAPMessage(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peername = st.nextToken(); - String appName = st.nextToken(); - String uri = st.nextToken(); - String message = st.nextToken(); - - // first - get storage - ASAPInternalStorage asapStorage = this.getEngine(peername, appName); - if(asapStorage == null) { - this.standardError.println("storage does not exist: " + peername + ":" + appName); - return; - } - asapStorage.add(uri, message); - } - catch(RuntimeException e) { - this.printUsage(CREATE_ASAP_MESSAGE, e.getLocalizedMessage()); - } catch (IOException | ASAPException e) { - this.printUsage(CREATE_ASAP_MESSAGE, e.getLocalizedMessage()); - } - } - - public void doResetASAPStorages() { - FSUtils.removeFolder(PEERS_ROOT_FOLDER); - File rootFolder = new File(PEERS_ROOT_FOLDER); - rootFolder.mkdirs(); - - } - - public void doSetSendReceivedMessage(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String storageName = st.nextToken(); - String onOff = st.nextToken(); - - boolean on = this.parseOnOffValue(onOff); - - ASAPEngine engine = this.getEngine(storageName); - engine.setBehaviourAllowRouting(on); - } - catch(RuntimeException | IOException | ASAPException e) { - this.printUsage(SET_SEND_RECEIVED_MESSAGES, e.getLocalizedMessage()); - } - } - - public void doPrintAllInformation() throws ASAPException { - try { - this.standardOut.println(this.peers.keySet().size() + " peers in folder: " + PEERS_ROOT_FOLDER); - for(String peername : this.peers.keySet()) { - this.standardOut.println("+++++++++++++++++++"); - this.standardOut.println("Peer: " + peername); - ASAPInternalPeer asapInternalPeer = this.peers.get(peername); - - for (CharSequence format : asapInternalPeer.getFormats()) { - ASAPEngine asapStorage = asapInternalPeer.getEngineByFormat(format); - this.standardOut.println("storage: " + format); - for (CharSequence uri : asapStorage.getChannelURIs()) { - this.printChannelInfo(asapStorage, uri, format); - } - } - this.standardOut.println("+++++++++++++++++++\n"); - } - } - catch(RuntimeException | IOException | ASAPException e) { - this.printUsage(PRINT_ALL_INFORMATION, e.getLocalizedMessage()); - } - } - - public void doPrintStorageInformation(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peername = st.nextToken(); - String appName = st.nextToken(); - - // first - get storage - ASAPInternalStorage asapStorage = this.getEngine(peername, appName); - if(asapStorage == null) { - this.standardError.println("storage does not exist: " + peername + ":" + appName); - return; - } - - // iterate URI - this.standardOut.println(asapStorage.getChannelURIs().size() + - " channels in storage " + appName + - " (note: channels without messages are considered non-existent)"); - for(CharSequence uri : asapStorage.getChannelURIs()) { - this.doPrintChannelInformation(parameterString + " " + uri); - } - } - catch(RuntimeException | IOException | ASAPException e) { - this.printUsage(PRINT_STORAGE_INFORMATION, e.getLocalizedMessage()); - } - } - - public void doSleep(String parameterString) throws ASAPException { - StringTokenizer st = new StringTokenizer(parameterString); - - try { - Thread.sleep(Long.parseLong(parameterString)); - } - catch(InterruptedException e) { - this.standardOut.println("sleep interrupted"); - } - catch(RuntimeException e) { - this.printUsage(PRINT_STORAGE_INFORMATION, e.getLocalizedMessage()); - } - } - - private void doShowLog() { - if(this.cmds.size() < 1) return; - - boolean first = true; - for(String c : this.cmds) { - if (!first) { - this.standardOut.println("\\n\" + "); - } else { - first = false; - } - this.standardOut.print("\""); - this.standardOut.print(c); - } - this.standardOut.println("\""); - } - - public void doPrintChannelInformation(String parameterString) throws ASAPException { - // out.println("example: " + PRINT_CHANNEL_INFORMATION + " Alice chat sn2://abChat"); - StringTokenizer st = new StringTokenizer(parameterString); - - try { - String peername = st.nextToken(); - String appName = st.nextToken(); - String uri = st.nextToken(); - - // first - get storage - ASAPInternalStorage asapStorage = this.getEngine(peername, appName); - if(asapStorage == null) { - this.standardError.println("storage does not exist: " + peername + ":" + appName); - return; - } - - this.printChannelInfo(asapStorage, uri, appName); - - } - catch(RuntimeException | ASAPException | IOException e) { - this.printUsage(CREATE_ASAP_MESSAGE, e.getLocalizedMessage()); - } - } - - private void printChannelInfo(ASAPInternalStorage asapStorage, CharSequence uri, CharSequence appName) - throws IOException, ASAPException { - - ASAPChannel channel = asapStorage.getChannel(uri); - Set recipients = channel.getRecipients(); - - this.standardOut.println("Peer:App:Channel == " + channel.getOwner() + ":" + appName + ":" + channel.getUri()); - this.standardOut.println("#Messages == " + channel.getMessages().size()); - this.standardOut.println("#Recipients == " + recipients.size() + - " (0 means: open channel - no restrictions - anybody receives from this channel)"); - for(CharSequence recipient : recipients) { - this.standardOut.println(recipient); - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // helper methods // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private String getUriFromStorageName(String storageName) throws ASAPException { - int i = storageName.indexOf(":"); - if(i < 0) throw new ASAPException("malformed storage name (missing \":\") " + storageName); - - return storageName.substring(i); - } - - private ASAPEngine getEngine(String storageName) throws ASAPException, IOException { - // split name into peer and storage - String[] split = storageName.split(":"); - - ASAPEngine asapEngine = this.getEngine(split[0], split[1]); - if(asapEngine == null) throw new ASAPException("no storage with name: " + storageName); - - return asapEngine; - } - - private boolean parseOnOffValue(String onOff) throws ASAPException { - if(onOff.equalsIgnoreCase("on")) return true; - if(onOff.equalsIgnoreCase("off")) return false; - - throw new ASAPException("unexpected value; expected on or off, found: " + onOff); - - } - - public String getEngineRootFolderByStorageName(String storageName) throws ASAPException, IOException { - ASAPEngineFS asapEngineFS = (ASAPEngineFS) this.getEngine(storageName); - return asapEngineFS.getRootFolder(); - } -} \ No newline at end of file diff --git a/src/main/java/net/sharksystem/asap/cmdline/ExampleASAPChunkReceivedListener.java b/src/main/java/net/sharksystem/asap/cmdline/ExampleASAPChunkReceivedListener.java deleted file mode 100644 index 31e97b5..0000000 --- a/src/main/java/net/sharksystem/asap/cmdline/ExampleASAPChunkReceivedListener.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.sharksystem.asap.cmdline; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.engine.ASAPChunkAssimilatedListener; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ASAP API: callbacks ASAPChunkReceived // -//////////////////////////////////////////////////////////////////////////////////////////////////////////// -public class ExampleASAPChunkReceivedListener implements ASAPChunkAssimilatedListener { - private final String rootFolder; - private List receivedList = new ArrayList<>(); - - public ExampleASAPChunkReceivedListener(String rootFolder) { - this.rootFolder = rootFolder; - } - - @Override - public void chunkStored(String format, String senderE2E, String uri, int era, - List asapHop) throws IOException { - - this.receivedList.add(new ASAPChunkReceivedParameters(format, senderE2E, uri, era)); - } - - @Override - public void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException { - Log.writeLog(this, "transient message received - TODO?"); - } - - public List getReceivedList() { return this.receivedList; } - - public class ASAPChunkReceivedParameters { - private final String format; - private final String sender; - private final String uri; - private final int era; - - private ASAPChunkReceivedParameters(String format, String sender, String uri, int era) { - Log.writeLog(this, "ASAPChunkReceivedParameters: chunk received: " + format + " | " + sender + " | " + uri); - this.format = format; - this.sender = sender; - this.uri = uri; - this.era = era; - } - - public String getFormat() { return this.format; } - public String getSender() { return this.sender; } - public String getUri() { return this.uri; } - public int getEra() { return this.era; } - } -} diff --git a/src/main/java/net/sharksystem/asap/cmdline/TCPASAPPeerFS.java b/src/main/java/net/sharksystem/asap/cmdline/TCPASAPPeerFS.java deleted file mode 100644 index d3cbd47..0000000 --- a/src/main/java/net/sharksystem/asap/cmdline/TCPASAPPeerFS.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.sharksystem.asap.cmdline; - -/** - * Run an ASAP peer that can communicate with TCP. It can offer an open tcp server socket. - * It can also be used as sub unit of a hub, see ASAPHub project. - * It works as an ordinary peer otherwise. It is meant to be used as a repeater. - */ -public class TCPASAPPeerFS { -} diff --git a/src/main/java/net/sharksystem/asap/cmdline/TCPStream.java b/src/main/java/net/sharksystem/asap/cmdline/TCPStream.java deleted file mode 100644 index 4a02beb..0000000 --- a/src/main/java/net/sharksystem/asap/cmdline/TCPStream.java +++ /dev/null @@ -1,241 +0,0 @@ -package net.sharksystem.asap.cmdline; - -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * - * @author thsc - */ -public class TCPStream extends Thread { - private final int port; - private final boolean asServer; - private final String name; - private TCPStreamCreatedListener listener = null; - private Socket socket = null; - - private boolean fatalError = false; - - public final int WAIT_LOOP_IN_MILLIS = 1000; // 30 sec - private Thread createThread = null; - private TCPServer tcpServer = null; - private TCPClient tcpClient = null; - private long waitInMillis = WAIT_LOOP_IN_MILLIS; - - public TCPStream(int port, boolean asServer, String name, TCPStreamCreatedListener listener) { - this.port = port; - this.asServer = asServer; - this.name = name; - this.listener = listener; - } - - public TCPStream(int port, boolean asServer, String name) { - this(port, asServer, name, null); - } - - public void setListener(TCPStreamCreatedListener listener) { - this.listener = listener; - } - - public void setWaitPeriod(long waitInMillis) { - this.waitInMillis = waitInMillis; - } - - public void kill() { - try { - if(this.socket != null) { - this.socket.close(); - } - - if(this.tcpClient != null) { - this.tcpClient.kill(); - } - - if(this.tcpServer != null) { - this.tcpServer.kill(); - } - } catch (IOException e) { - Log.writeLogErr(this, "TCPChannel: problems while killing: " + e.getLocalizedMessage()); - } - } - - @Override - public void run() { - this.createThread = Thread.currentThread(); - try { - if(this.asServer) { - Log.writeLog(this, - "TCPChannel: note: this implementation will only accept *one* connection attempt as server"); - this.tcpServer = new TCPServer(); - this.socket = tcpServer.getSocket(); - } else { - this.tcpClient = new TCPClient(); - this.socket = this.tcpClient.getSocket(); - } - - // we have got a socket - if(this.listener != null) { - this.listener.streamCreated(this); - } - } catch (IOException ex) { - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - throw new IOException(s); - } - } - - public InputStream getInputStream() throws IOException { - this.checkConnected(); - return this.socket.getInputStream(); - } - - public OutputStream getOutputStream() throws IOException { - this.checkConnected(); - return this.socket.getOutputStream(); - } - - private class TCPServer { - private ServerSocket srvSocket = null; - - Socket getSocket() throws IOException { - if(this.srvSocket == null) { - this.srvSocket = new ServerSocket(port); - } - - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - Socket socket = this.srvSocket.accept(); - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - return socket; - } - - public void kill() throws IOException { - this.srvSocket.close(); - } - } - - private class TCPClient { - private boolean killed = false; - - public void kill() { - this.killed = true; - } - - Socket getSocket() throws IOException { - while(!this.killed) { - try { - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - Socket socket = new Socket("localhost", port); - return socket; - } - catch(IOException ioe) { - //<<<<<<<<<<<<<<<<< peerKeyPairs = new HashMap<>(); - - private HashMap peerPublicKeys = new HashMap(); - - /** - * Setup key store, A key pair will be generated - * @param ownerID - * @throws ASAPSecurityException - */ - public InMemoASAPKeyStore(CharSequence ownerID) throws ASAPSecurityException { - // generate owners key pair; - this.ownerID = ownerID; - //this.generateKeyPair(); - } - - /** - * Setup key store with a key pair - * @param ownerID - * @param ownerKeyPair - * @deprecated - */ - public InMemoASAPKeyStore(CharSequence ownerID, KeyPair ownerKeyPair, long keyPairCreationTime) { - this.ownerID = ownerID; - this.keyPair = ownerKeyPair; - if(ownerKeyPair != null) { - this.privateKey = ownerKeyPair.getPrivate(); - this.publicKey = ownerKeyPair.getPublic(); - } - - this.keyPairCreationTime = keyPairCreationTime; - } - - protected void setKeyPair(KeyPair keyPair) { - this.keyPair = keyPair; - } - - public KeyPair getKeyPair() { - if(this.keyPair == null) { - Log.writeLog(this, "key pair not yet generated - do it now"); - try { - this.generateKeyPair(); - } catch (ASAPSecurityException e) { - Log.writeLogErr(this, "cannot generate key pair - fatal"); - e.printStackTrace(); - return null; - } - } - return this.keyPair; - } - - public SecretKey generateSymmetricKey() throws ASAPSecurityException { - return ASAPCryptoAlgorithms.generateSymmetricKey( - DEFAULT_SYMMETRIC_KEY_TYPE, DEFAULT_SYMMETRIC_KEY_SIZE); - } - - public long getKeysCreationTime() throws ASAPSecurityException { - return this.keyPairCreationTime; - } - - public int getSymmetricKeyLen() { - return ASAPKeyStore.DEFAULT_SYMMETRIC_KEY_SIZE; - } - - public void generateKeyPair() throws ASAPSecurityException { - this.setKeyPair(this.generateNewKeyPair()); - this.privateKey = this.keyPair.getPrivate(); - this.publicKey = this.keyPair.getPublic(); - this.keyPairCreationTime = System.currentTimeMillis(); - this.save(); - } - - private KeyPair generateNewKeyPair() throws ASAPSecurityException { - Log.writeLog(this, "create key pair"); - KeyPairGenerator keyGen = null; - try { - keyGen = KeyPairGenerator.getInstance("RSA"); - } catch (NoSuchAlgorithmException e) { - throw new ASAPSecurityException(e.getLocalizedMessage()); - } - - SecureRandom secRandom = new SecureRandom(); - try { - keyGen.initialize(2048, secRandom); - return keyGen.generateKeyPair(); - } - catch(RuntimeException re) { - throw new ASAPSecurityException(re.getLocalizedMessage()); - } - } - - public KeyPair createTestPeer(String id) throws ASAPSecurityException { - KeyPair keyPair = this.generateNewKeyPair(); - this.peerKeyPairs.put(id, keyPair); - return keyPair; - } - - private void checkKeyPairExistence() throws ASAPSecurityException { - if(this.keyPair == null) { - Log.writeLog(this, "create new keypair since requested but missing"); - this.generateKeyPair(); - this.privateKey = this.keyPair.getPrivate(); - this.publicKey = this.keyPair.getPublic(); - } - } - - @Override - public PrivateKey getPrivateKey() throws ASAPSecurityException { - if(this.privateKey == null) { - this.checkKeyPairExistence(); - } - return this.privateKey; - } - - @Override - public PublicKey getPublicKey() throws ASAPSecurityException { - if(this.publicKey == null) { - this.checkKeyPairExistence(); - } - return this.publicKey; - } - - @Override - public PublicKey getPublicKey(CharSequence subjectID) throws ASAPSecurityException { - KeyPair keyPair = this.peerKeyPairs.get(subjectID); - if(keyPair == null) { - // try there - which is more likely - PublicKey publicKey = this.peerPublicKeys.get(subjectID); - if(publicKey != null) { - // got it - return publicKey; - } - // else - throw new ASAPSecurityException("no key pair for " + subjectID); - } - - return keyPair.getPublic(); - } - - void putPublicKey(CharSequence peer, PublicKey key) { - this.peerPublicKeys.put(peer, key); - } - - /** - * In reality there cannot be such a method - but we are in a test. - * @param subjectID - * @return - * @throws ASAPSecurityException - */ - public PrivateKey getPrivateKey(CharSequence subjectID) throws ASAPSecurityException { - KeyPair keyPair = this.peerKeyPairs.get(subjectID); - if(keyPair == null) throw new ASAPSecurityException("no key pair for " + subjectID); - - return keyPair.getPrivate(); - } - - @Override - public String getAsymmetricEncryptionAlgorithm() { - return DEFAULT_ASYMMETRIC_ENCRYPTION_ALGORITHM; - } - - @Override - public String getSymmetricEncryptionAlgorithm() { - return DEFAULT_SYMMETRIC_ENCRYPTION_ALGORITHM; - } - - @Override - public String getSymmetricKeyType() { - return DEFAULT_SYMMETRIC_KEY_TYPE; - } - - @Override - public boolean isOwner(CharSequence peerID) { - return ASAPCryptoAlgorithms.sameID(this.getOwner(), peerID); - } - - @Override - public CharSequence getOwner() { - return this.ownerID; - } - - @Override - public String getAsymmetricSigningAlgorithm() { - return DEFAULT_ASYMMETRIC_SIGNATURE_ALGORITHM; - } - - public void addKeyPair(String peerID, KeyPair keyPair) { - this.peerKeyPairs.put(peerID, keyPair); - } - - /** - * Write storage owners' public key to stream - * @param os - */ - public void writePublicKey(OutputStream os) throws ASAPSecurityException, IOException { - PublicKey publicKey = this.getPublicKey(); - - String format = publicKey.getFormat(); - String algorithm = publicKey.getAlgorithm(); - byte[] byteEncodedPublicKey = publicKey.getEncoded(); - int length = byteEncodedPublicKey.length; - - // makes it much easier to serialize simple data - DataOutputStream dos = new DataOutputStream(os); - - // write to stream - dos.writeUTF(format); - dos.writeUTF(algorithm); - dos.writeInt(byteEncodedPublicKey.length); - - // write encoded key directly on stream - os.write(byteEncodedPublicKey); - } - - /** - * Read public key from another peer from an extern source (input stream) - * @param peer - * @param is - */ - public void readPublicKey(CharSequence peer, InputStream is) throws ASAPSecurityException, IOException, NoSuchAlgorithmException, InvalidKeySpecException { - DataInputStream dis = new DataInputStream(is); - - // read in same order as written - String format = dis.readUTF(); - String algorithm = dis.readUTF(); - int len = dis.readInt(); - - // allocate memory - byte[] byteEncodedPublicKey = new byte[len]; - - // read encoded key directly from stream - is.read(byteEncodedPublicKey); - - // create key object - - // should be revised - why? - X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(byteEncodedPublicKey); - - KeyFactory keyFactory = KeyFactory.getInstance(algorithm); - PublicKey publicKey = keyFactory.generatePublic(pubKeySpec); - - // store it - this.putPublicKey(peer, publicKey); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // persist // - ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private ExtraData mementoExtraData; - - public void setMementoTarget(ExtraData extraData) { - this.mementoExtraData = extraData; - try { - byte[] memento = this.mementoExtraData.getExtra(ASAP_KEYSTORE_MEMENTO_KEY); - this.restoreMemento(memento); - } catch (IOException | SharkException e) { - // no memento - hm, maybe was set when this keystore was already running - better save - this.save(); - } - } - - private void save() { - if(this.mementoExtraData != null) { - try { - this.mementoExtraData.putExtra(ASAP_KEYSTORE_MEMENTO_KEY, this.getMemento()); - } catch (IOException | SharkException e) { - Log.writeLogErr(this, "cannot write memento: " + e.getLocalizedMessage()); - } - } else { - Log.writeLog(this, "cannot write data - no persistent storage"); - } - } - - public byte[] getMemento() throws ASAPException, IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - // encoded private key - ASAPSerialization.writeByteArray(this.getPrivateKey().getEncoded(), baos); - // private key algorithm - ASAPSerialization.writeCharSequenceParameter(this.getPrivateKey().getAlgorithm(), baos); - // private key format - ASAPSerialization.writeCharSequenceParameter(this.getPrivateKey().getFormat(), baos); - - // public key encoded - ASAPSerialization.writeByteArray(this.getPublicKey().getEncoded(), baos); - // public key algorithm - ASAPSerialization.writeCharSequenceParameter(this.getPublicKey().getAlgorithm(), baos); - // public key format - ASAPSerialization.writeCharSequenceParameter(this.getPublicKey().getFormat(), baos); - - // creation time - ASAPSerialization.writeLongParameter(this.keyPairCreationTime, baos); - - // ownerID - ASAPSerialization.writeCharSequenceParameter(this.ownerID, baos); - - return baos.toByteArray(); - } - - public void restoreMemento(byte[] mementoData) throws IOException, ASAPException { - ByteArrayInputStream bais = new ByteArrayInputStream(mementoData); - - byte[] privateKeyBytes = ASAPSerialization.readByteArray(bais); - String privateKeyAlgorithm = ASAPSerialization.readCharSequenceParameter(bais); - String privateKeyFormat = ASAPSerialization.readCharSequenceParameter(bais); - - byte[] publicKeyBytes = ASAPSerialization.readByteArray(bais); - String publicKeyAlgorithm = ASAPSerialization.readCharSequenceParameter(bais); - String publicKeyFormat = ASAPSerialization.readCharSequenceParameter(bais); - - // reproduce private key - // as to be seen, pretty limited alg/format support yet :/ - try { - KeyFactory kf = KeyFactory.getInstance("RSA"); - this.privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); - this.publicKey = kf.generatePublic(new X509EncodedKeySpec(publicKeyBytes)); - } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { - throw new ASAPException("cannot restore keystore form memento: " + e.getLocalizedMessage()); - } - - // reset those simple data after that critical stuff. - this.keyPairCreationTime = ASAPSerialization.readLongParameter(bais); - this.ownerID = ASAPSerialization.readCharSequenceParameter(bais); - - Log.writeLog(this, "restored keys"); - } -} diff --git a/src/main/java/net/sharksystem/asap/crypto/SharkCryptoException.java b/src/main/java/net/sharksystem/asap/crypto/SharkCryptoException.java deleted file mode 100644 index c8b3c6b..0000000 --- a/src/main/java/net/sharksystem/asap/crypto/SharkCryptoException.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sharksystem.asap.crypto; - -import net.sharksystem.asap.ASAPException; - -public class SharkCryptoException extends ASAPException { - public SharkCryptoException() { super(); } - - public SharkCryptoException(String message) { super(message); } - - public SharkCryptoException(String message, Throwable cause) { super(message, cause); } - - public SharkCryptoException(Throwable cause) { super(cause); } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPAbstractOnlineMessageSender.java b/src/main/java/net/sharksystem/asap/engine/ASAPAbstractOnlineMessageSender.java deleted file mode 100644 index bf537f9..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPAbstractOnlineMessageSender.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; - -import java.io.IOException; -import java.util.*; - -public abstract class ASAPAbstractOnlineMessageSender implements ASAPOnlineMessageSender { - private ASAPInternalStorage source = null; - - public void attachToSource(ASAPInternalStorage source) { - source.attachASAPMessageAddListener(this); - } - - public void detachFromStorage() { - if(this.source != null) { - this.source.detachASAPMessageAddListener(); - } - } - - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, CharSequence recipient, - byte[] messageAsBytes, int era) throws IOException, ASAPException { - if(recipient == null) { - this.sendASAPAssimilateMessage(format, uri, messageAsBytes, era); - } else { - Set recipients = new HashSet<>(); - recipients.add(recipient); - this.sendASAPAssimilateMessage(format, uri, recipients, messageAsBytes, era); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPChannelImpl.java b/src/main/java/net/sharksystem/asap/engine/ASAPChannelImpl.java deleted file mode 100644 index d3955a5..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPChannelImpl.java +++ /dev/null @@ -1,97 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -public class ASAPChannelImpl implements ASAPChannel { - private static final String CHANNEL_OWNER = "ASAPChannelOwner"; - private final ASAPEngine asapEngine; - private final CharSequence uri; - - public ASAPChannelImpl(ASAPEngine asapEngine, CharSequence uri) { - this.asapEngine = asapEngine; - this.uri = uri; - } - - @Override - public CharSequence getOwner() throws IOException { - return this.asapEngine.getExtra(this.getUri(), CHANNEL_OWNER); - } - - @Override - public CharSequence getUri() throws IOException { - return this.uri; - } - - @Override - public Set getRecipients() throws IOException { - return this.asapEngine.getRecipients(this.getUri()); - } - - @Override - public HashMap getExtraData() throws IOException { - return this.asapEngine.getStorage().getChunk(uri, this.asapEngine.getEra()).getExtraData(); - } - - @Override - public void putExtraData(String key, String value) throws IOException { - this.asapEngine.getStorage().getChunk(uri, this.asapEngine.getEra()).putExtra(key, value); - } - - @Override - public void removeExtraData(String key) throws IOException { - this.asapEngine.getStorage().getChunk(uri, this.asapEngine.getEra()).removeExtra(key); - } - - @Override - public ASAPMessages getMessages() throws IOException { - return this.asapEngine.getChunkStorage().getASAPMessages(this.getUri(), this.asapEngine.getEra()); - } - - @Override - public ASAPMessages getMessages(boolean peerOnly) throws IOException, ASAPException { - if(peerOnly) return this.getMessages(); - // else - return this.getMessages(null); - } - - @Override - public ASAPMessages getMessages(ASAPMessageCompare compare) throws IOException, ASAPException { - List messagesSource = new ArrayList<>(); - - // add message from local peer first - messagesSource.add(this.getMessages()); - - // other sender? - List sender = this.asapEngine.getSender(); - for(CharSequence senderID : sender) { - try { - ASAPStorage existingIncomingStorage = this.asapEngine.getExistingIncomingStorage(senderID); - int currentEra = existingIncomingStorage.getEra(); - // want all messages - int beforeCurrentEra = ASAP.previousEra(currentEra); - // currentEra -> direct predecessor - messagesSource.add(existingIncomingStorage.getChunkStorage().getASAPMessages( - this.getUri(), currentEra, beforeCurrentEra)); - } catch (ASAPException e) { - // no such storage - ok ignore and go ahead - } - } - - return new ASAPMessagesMerger(messagesSource, compare); - } - - @Override - public void addMessage(byte[] message) throws IOException { - this.asapEngine.add(this.uri, message); - } - - public void setOwner(CharSequence owner) throws IOException { - this.asapEngine.putExtra(this.getUri(), CHANNEL_OWNER, owner.toString()); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPChunkAssimilatedListener.java b/src/main/java/net/sharksystem/asap/engine/ASAPChunkAssimilatedListener.java deleted file mode 100644 index 48bc63b..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPChunkAssimilatedListener.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessages; - -import java.io.IOException; -import java.util.List; - -/** - * - * @author thsc - */ -public interface ASAPChunkAssimilatedListener { - /** - * Announce incoming ASAP messages. Note the important difference of both senders. ASAP is a routing protocol. - * An ASAP message has got an original sender (the end-to-end (E2E) sender). Other peers can route this message. - * The final (senderPoint2Point) is not necessarily the E2E sender but the peer on the other side of the channel. - *

- * E2E sender and direct sender are always the same when disengaging routing. - * It is recommended to allow routing, though. - * - * @param format application format - * @param senderE2E original sender peer - the E2E sender - not necessarily the sender on the other side of - * the channel. - * @param uri message uri - * @param era era of the original sender (the end-to-end sender). not - * @param asapHop describes the point-to-point message exchhange in more details - * @see ASAPHop - * - */ - void chunkStored(String format, String senderE2E, String uri, int era, // E2E part - List asapHop) throws IOException; - - void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPChunkStorageFS.java b/src/main/java/net/sharksystem/asap/engine/ASAPChunkStorageFS.java deleted file mode 100644 index 648fc84..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPChunkStorageFS.java +++ /dev/null @@ -1,183 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.utils.Utils; -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.utils.Log; -import net.sharksystem.fs.FSUtils; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static net.sharksystem.asap.engine.ASAPInternalChunkFS.META_DATA_EXTENSION; - -/** - * - * @author thsc - */ -class ASAPChunkStorageFS implements ASAPChunkStorage { - private final String rootDirectory; - private final String format; - private int era = -1; - - ASAPChunkStorageFS(String rootDirectory, String format) { - this.rootDirectory = rootDirectory; - this.format = format; - } - - ASAPChunkStorageFS(String rootDirectory, String format, int era) { - this.rootDirectory = rootDirectory; - this.format = format; - this.era = era; - } - - public String getFormat() { - return this.format; - } - - public String getRootDirectory() { - return this.rootDirectory; - } - - @Override - public ASAPInternalChunk getChunk(CharSequence uriTarget, int era) throws IOException { - return new ASAPInternalChunkFS(this, uriTarget.toString(), era); - } - - @Override - public boolean existsChunk(CharSequence uri, int era) throws IOException { - String fullContentFileName = this.getChunkContentFilename(era, uri); - - boolean exists = (new File(fullContentFileName).exists()); - return exists; - } - - String getChunkContentFilename(int era, CharSequence uri) { - return this.getChunkFileTrunkname(era, uri.toString()) + "." + META_DATA_EXTENSION; - } - - String getChunkFileTrunkname(int era, String uri) { - return this.getPath(era) + "/" + Utils.url2FileName(uri); - } - - /** - * - * @param era - * @param targetUrl - * @return full name (path/name) of that given url and target. Directories - * are created if necessary. - */ - String setupChunkFolder(int era, String targetUrl) { - String eraFolderString = this.getPath(era); - File eraFolder = new File(eraFolderString); - //Log.writeLog(this, "produced chunk folder name: " + eraFolderString); - if(!eraFolder.exists()) { - //Log.writeLog(this, "folder does not exist - create: " + eraFolderString); - eraFolder.mkdirs(); - } - - //Log.writeLog(this, "chunk folder exists: " + eraFolder); - String fileNameWithoutExtension = eraFolderString + "/" + Utils.url2FileName(targetUrl); - //Log.writeLog(this, "use this file name to store chunk (meta)data: " + fileNameWithoutExtension); - return fileNameWithoutExtension; - } - - /** - * - * @param era - * @return full name (path/name) of that given url and target. Directories - * are expected to be existent - */ - String getFileNameByUri(int era, String uri) { - return this.getPath(era) + "/" + uri; - } - - private String getPath(int era) { - return this.rootDirectory + "/" + Integer.toString(era); - } - - @Override - public List getChunks(int era) throws IOException { - List chunkList = new ArrayList<>(); - - File dir = new File(this.getPath(era)); - - // can be null! - File[] contentFileList = dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String fileName) { - return fileName.endsWith(META_DATA_EXTENSION); - } - }); - - if(contentFileList != null) { - for (int i = 0; i < contentFileList.length; i++) { - String name = contentFileList[i].getName(); - - // cut extension - int index = name.lastIndexOf('.'); - if(index != -1) { - String chunkName = name.substring(0, index); - String fName = this.getFileNameByUri(era, chunkName); - chunkList.add(new ASAPInternalChunkFS(this, fName)); - } - } - } - - return chunkList; - } - - @Override - public void dropChunks(int era) throws IOException { - // here comes a Java 6 compatible version - fits to android SDK 23 - String eraPathName = this.rootDirectory + "/" + Integer.toString(era); - - FSUtils.removeFolder(eraPathName); - } - - @Override - public ASAPMessages getASAPMessages(CharSequence uri, int toEra) throws IOException { - // INIT ++++++++++++++++++++++ toEra +++++++++++++++++++++ MAX - - int fromEra = ASAP.nextEra(toEra); // the whole cycle - return this.getASAPMessages(uri, fromEra, toEra); - } - - @Override - public ASAPMessages getASAPMessages(CharSequence uri, int fromEra, int toEra) throws IOException { - Log.writeLog(this, "create ASAPInMemoMessages"); - - return new ASAPInMemoMessages( - this, - this.getFormat(), - uri, - fromEra, // set starting era - toEra // anything before - ); - } - - @Override - public ASAPMessages getASAPMessages(String uri) throws ASAPException, IOException { - if(this.era == -1) { - throw new ASAPException("internal error: era not set - use other constructor or method"); - } - return this.getASAPMessages(uri, this.era); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()); - sb.append(": "); - sb.append(this.rootDirectory); - sb.append(" | "); - sb.append(this.format); - sb.append(" | "); - sb.append(this.era); - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPCommunicationSetting.java b/src/main/java/net/sharksystem/asap/engine/ASAPCommunicationSetting.java deleted file mode 100644 index 0e2f594..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPCommunicationSetting.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.protocol.ASAP_AssimilationPDU_1_0; - -interface ASAPCommunicationSetting { - boolean allowedToCreateChannel(ASAP_AssimilationPDU_1_0 asapAssimilationPDU); - - /** - * @param on if true - message must be encrypted - */ - void setSendEncryptedMessages(boolean on); - - /** - * @param on if true - message must be signed - */ - void setSendSignedMessages(boolean on); - -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPEngine.java b/src/main/java/net/sharksystem/asap/engine/ASAPEngine.java deleted file mode 100644 index d35103c..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPEngine.java +++ /dev/null @@ -1,975 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPHopImpl; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.*; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.listenermanager.management.ASAPManagementStorage; -import net.sharksystem.asap.listenermanager.management.ASAPManagementStorageImpl; -import net.sharksystem.asap.protocol.*; -import net.sharksystem.asap.utils.PeerIDHelper; -import net.sharksystem.utils.Log; -import net.sharksystem.asap.crypto.ASAPPoint2PointCryptoSettings; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.*; - -/** - * That ASAPEngine manages exchange of stored messages with peers. - * See ASPChunkStorage for details. - * - * @see ASAPInternalStorage - * @author thsc - */ -public abstract class ASAPEngine extends ASAPStorageImpl implements ASAPInternalStorage, ASAPProtocolEngine, ASAPManagementStorage { - private DefaultSecurityAdministrator securityAdministrator; - - public void setSecurityAdministrator(DefaultSecurityAdministrator securityAdministrator) { - this.securityAdministrator = securityAdministrator; - } - - public static final String ANONYMOUS_OWNER = "anon"; - static String DEFAULT_OWNER = ANONYMOUS_OWNER; - static int DEFAULT_INIT_ERA = 0; - - protected String owner = ANONYMOUS_OWNER; - - protected int era = ASAP.INITIAL_ERA; - protected int oldestEra = ASAP.INITIAL_ERA; - protected HashMap lastSeen = new HashMap<>(); - protected ASAPMemento memento = null; - public long lastMementoWritten; - - protected boolean dropDeliveredChunks = false; - - private ASAPOnlineMessageSender asapOnlineMessageSender; - protected boolean contentChanged = false; - protected boolean routingAllowed = true; - - protected ASAPEngine(ASAPChunkStorage chunkStorage, CharSequence chunkContentFormat) - throws ASAPException, IOException { - //super(chunkStorage, chunkContentFormat); - - this.chunkStorage = chunkStorage; - if(chunkContentFormat != null) { - this.format = chunkContentFormat.toString(); - } else { - throw new ASAPException("format expected. like application/x-sn2-makan"); - } - } - - private void saveStatus() throws IOException { - if (this.memento != null) { - this.memento.save(this); - } - } - - CryptoControl getCryptoControl() { - return this.securityAdministrator; - } - - public ASAPEnginePermissionSettings getASAPEnginePermissionSettings() { - return this.securityAdministrator; - } - - public ASAPCommunicationSetting getASAPCommunicationControl() { - return this.securityAdministrator; - } - - public ASAPPoint2PointCryptoSettings getASAPCommunicationCryptoSettings() { - return this.securityAdministrator; - } - - public void attachASAPMessageAddListener(ASAPOnlineMessageSender asapOnlineMessageSender) { - this.asapOnlineMessageSender = asapOnlineMessageSender; - } - - public void detachASAPMessageAddListener() { - this.asapOnlineMessageSender = null; - } - - /** - * We interpret an existing chunk with *no* recipients as - * public chunk - * @param chunk - * @return - */ - private boolean isPublic(ASAPInternalChunk chunk) { - return chunk.getRecipients().isEmpty(); - } - - abstract void syncMemento() throws IOException; - - @Override - public void newEra() { - this.newEra(false, -1); - } - - /** - * Set a new ear in this storage - if forced: set newEra as specified without questioning - * @param force - * @param nextEra - */ - private void newEra(boolean force, int nextEra) { - try { - this.syncMemento(); - } catch (IOException e) { - Log.writeLogErr(this, this.toString(),"cannot read memento: " + e.getLocalizedMessage()); - } - - if(force || this.contentChanged) { - // set as fast as possible to make race conditions less likely - this.contentChanged = false; - - if(force) { - Log.writeLog(this, this.toString(), "forced setting era to " + nextEra); - } else { - // calculate new era - nextEra = nextEra < 0 ? this.getNextEra(this.era) : nextEra; - Log.writeLog(this, this.toString(), "era not forced - incremented era to " + nextEra); - } - try { - int previousEra = this.era; - - // we are done here - we are in a new era. - this.era = nextEra; - - // persistent values - if(this.memento != null) this.memento.save(this); - - /* now: - previousEra .. era that was used a few milliseconds before. Keep it. - this.era .. era we are going to work with - - Now, there could be a very old version with same number as this.era - remove it before you set up - fresh era - */ - - if(this.era == previousEra) { - Log.writeLog(this, this.toString(), "this.era == previousEra - nothing to do"); - } else { - // drop very very old chunks - if available - if not - don't care - this.getChunkStorage().dropChunks(this.era); - - Log.writeLog(this, this.toString(), - "setup new era by cloning previous chunk meta data: " - + this.era + " <- " + previousEra); - // setup new era - copy all chunks - for(ASAPInternalChunk chunk : this.getChunkStorage().getChunks(previousEra)) { - Log.writeLog(this, this.toString(),"going to clone: " + chunk); - ASAPInternalChunk copyChunk = this.getChunkStorage().getChunk(chunk.getUri(), this.era); - copyChunk.clone(chunk); - Log.writeLog(this, this.toString(),"done cloning: " + copyChunk); - } - } - - Log.writeLog(this, this.toString(), "era incremented"); - } catch (IOException ex) { - ex.printStackTrace(); - Log.writeLogErr(this, this.toString(), - "IOException while incrementing era: " + ex.getLocalizedMessage()); - } - } else { - Log.writeLog(this, this.toString(), "content not changed - era not changed"); - } - } - - ////////////////////////////////////////////////////////////////////// - // Writer // - ////////////////////////////////////////////////////////////////////// - - @Override - public void createChannel(CharSequence uri, Collection recipients) throws IOException, ASAPException { - this.createChannel(this.getOwner(), uri, recipients); - } - - @Override - public void createChannel(CharSequence owner, CharSequence uri, Collection recipients) - throws IOException, ASAPException { - - this.setRecipients(uri, recipients); - this.getASAPChannelImpl(uri).setOwner(owner); - - // inform recipients about that event - if(this.isASAPManagementStorageSet()) { - this.getASAPManagementStorage().notifyChannelCreated(this.format, owner, uri, recipients); - } else { - Log.writeLog(this, this.toString(), "asap management storage not set - no propagation of channel creation"); - } - } - - public void createChannel(CharSequence urlTarget) throws IOException, ASAPException { - this.createChannel(urlTarget, (CharSequence) null); - } - - @Override - public void createChannel(CharSequence urlTarget, CharSequence recipient) throws IOException, ASAPException { - Set recipients = new HashSet<>(); - recipients.add(recipient); - this.createChannel(urlTarget, recipients); - } - - private ASAPManagementStorage asapManagementStorage = null; - public void setASAPManagementStorage(ASAPManagementStorage asapManagementStorage) { - this.asapManagementStorage = asapManagementStorage; - } - - public ASAPManagementStorage getASAPManagementStorage() throws IOException, ASAPException { - if(this.asapManagementStorage == null) { - throw new ASAPException("ASAP Management Storage not set"); - } - - return this.asapManagementStorage; - } - - public boolean isASAPManagementStorageSet() { - return this.asapManagementStorage != null; - } - - public void notifyChannelCreated(CharSequence appName, CharSequence owner, - CharSequence uri, Collection recipients) - throws ASAPException, IOException { - - new ASAPManagementStorageImpl(this).notifyChannelCreated(appName, owner, uri, recipients); - } - - public void addRecipient(CharSequence urlTarget, CharSequence recipient) throws IOException { - this.chunkStorage.getChunk(urlTarget, this.era).addRecipient(recipient); - } - - public void setRecipients(CharSequence urlTarget, Collection recipients) throws IOException { - this.chunkStorage.getChunk(urlTarget, this.era).setRecipients(recipients); - } - - public Set getRecipients(CharSequence urlTarget) throws IOException { - return this.chunkStorage.getChunk(urlTarget, this.era).getRecipients(); - } - - public void removeRecipient(CharSequence urlTarget, CharSequence recipient) throws IOException { - this.chunkStorage.getChunk(urlTarget, this.era).removeRecipient(recipient); - } - - @Override - public void add(CharSequence uri, CharSequence message) throws IOException { - this.add(uri, message.toString().getBytes()); - } - - @Override - public void add(CharSequence uri, byte[] messageAsBytes) throws IOException { -// Log.writeLog(this, this.toString(), "reached add(uri, byte[] message"); - ASAPInternalChunk chunk = this.chunkStorage.getChunk(uri, this.era); - -// Log.writeLog(this, this.toString(), "call chunk.addMessage()"); - chunk.addMessage(messageAsBytes); - - // remember - something changed in that era - this.contentChanged(); - -// Log.writeLog(this, this.toString(), "online?"); - if(this.asapOnlineMessageSender != null) { - try { - Log.writeLog(this, this.toString(), "send online message..."); - this.asapOnlineMessageSender.sendASAPAssimilateMessage( - this.format, uri, chunk.getRecipients(), - messageAsBytes, this.era); - } catch (IOException | ASAPException e) { - Log.writeLog(this, this.toString(), - "message written to local storage - but could not write to open asap connection: " + - e.getLocalizedMessage()); - } - Log.writeLog(this, this.toString(), "... done sending online message"); - } else { - Log.writeLog(this, this.toString(), "online sending not active"); - } - } - - private void contentChanged() throws IOException { - this.contentChanged = true; - Log.writeLog(this, this.toString(), "content changed - save status"); - this.saveStatus(); - } - - private final ASAPChunkStorage chunkStorage; - protected String format = ASAP_1_0.ANY_FORMAT.toString(); - - @Override - public ASAPChunkStorage getChunkStorage() { - return this.chunkStorage; - } - - - @Override - public ASAPInternalChunk createNewChunk(String uri, int newEra) throws IOException { - ASAPInternalChunk chunk = this.getChunkStorage().getChunk(uri, newEra); - // set new era - this.newEra(true, newEra); - return chunk; - } - - ASAPChunkStorage getStorage() { - return this.chunkStorage; - } - - @Override - public void putExtra(CharSequence uri, String key, String value) throws IOException { - this.chunkStorage.getChunk(uri, this.era).putExtra(key, value); - } - - @Override - public CharSequence removeExtra(CharSequence uri, String key) throws IOException { - return this.chunkStorage.getChunk(uri, this.era).removeExtra(key); - } - - @Override - public CharSequence getExtra(CharSequence uri, String key) throws IOException { - return this.chunkStorage.getChunk(uri, this.era).getExtra(key); - } - - - public List getChannelURIs() throws IOException { - List uriList = new ArrayList<>(); - - List chunks = this.chunkStorage.getChunks(this.era); - for(ASAPInternalChunk chunk : chunks) { - uriList.add(chunk.getUri()); - } - - return uriList; - } - - @Override - public ASAPChannel getChannel(CharSequence uri) throws ASAPException, IOException { - return this.getASAPChannelImpl(uri); - } - - private ASAPChannelImpl getASAPChannelImpl(CharSequence uri) throws ASAPException, IOException { - if(this.channelExists(uri)) { - return new ASAPChannelImpl(this, uri); - } - - throw new ASAPException("channel with this uri does not exist: " + uri); - } - - @Override - public boolean channelExists(CharSequence uri) throws IOException { - return this.chunkStorage.existsChunk(uri, this.getEra()); - } - - public void removeChannel(CharSequence uri) throws IOException { - int currentEra; - int nextEra = this.getOldestEra(); - do { - currentEra = nextEra; - ASAPInternalChunk chunk = this.chunkStorage.getChunk(uri, currentEra); - chunk.drop(); - nextEra = ASAP.nextEra(currentEra); - } while(currentEra != this.getEra()); - } - - public ASAPMessages getChunkChain(int uriPosition) throws IOException, ASAPException { - return this.getChunkChain(uriPosition, this.era); - } - - public ASAPMessages getChunkChain(CharSequence uri, int toEra) throws IOException { - return this.chunkStorage.getASAPMessages(uri, toEra); - } - - public ASAPMessages getChunkChain(CharSequence uri) throws IOException { - return this.getChunkChain(uri, this.getEra()); - } - - public ASAPMessages getChunkChain(int uriPosition, int toEra) - throws IOException, ASAPException { - - List channelURIs = this.getChannelURIs(); - if(channelURIs.size() - 1 < uriPosition) { - throw new ASAPException("position greater than number of channels"); - } - - CharSequence uri = channelURIs.get(uriPosition); - if(uri == null) { - throw new ASAPException("uri at postion is null. Position: " + uriPosition); - } - - return this.chunkStorage.getASAPMessages(uri, toEra); - } - - ////////////////////////////////////////////////////////////////////// - // ProtocolEngine // - ////////////////////////////////////////////////////////////////////// - - // extract those algorithms to another class (ASAPDefaultProtocolEngine) ?! - public void handleASAPAssimilate(ASAP_AssimilationPDU_1_0 asapAssimilationPDU, ASAP_1_0 protocolModem, - String encounteredPeer, InputStream is, OutputStream os, ASAPEncounterConnectionType connectionType, - ASAPChunkAssimilatedListener listener) throws ASAPException, IOException { - - // before we start - lets crypto - if(!hasSufficientCrypto(asapAssimilationPDU)) return; - - String senderE2E = asapAssimilationPDU.getSender(); - int eraSender = asapAssimilationPDU.getEra(); - - // debug break - //if(PeerIDHelper.sameID(senderE2E, "Alice_42")) { int i = 42; } - - if(PeerIDHelper.sameID(senderE2E, this.owner)) { - Log.writeLogErr(this, this.toString(), "I was offered messages from myself (" - + this.owner + ") by " + encounteredPeer + " - refused: "); - asapAssimilationPDU.takeDataFromStream(); - return; - } - - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - boolean changed = false; - boolean allowedAssimilation = true; - - ASAPInternalChunk incomingChunk = null; - MessagesContainer messagesContainer = null; - ASAPInMemoTransientMessages transientMessages = null; - - ASAPHop lastHop = new ASAPHopImpl(encounteredPeer, asapAssimilationPDU.verified(), - asapAssimilationPDU.encrypted(), connectionType); - - try { - if(eraSender != ASAP.TRANSIENT_ERA) { - incomingChunk = this.getIncomingChunk(encounteredPeer, asapAssimilationPDU); - messagesContainer = incomingChunk; - } else { - transientMessages = - new ASAPInMemoTransientMessages(asapAssimilationPDU, lastHop); - - messagesContainer = transientMessages; - } - } - catch(ASAPException e) { - asapAssimilationPDU.takeDataFromStream(); - throw e; - } - - // put messages into container - incoming chunk or transient message container - List messageOffsets = asapAssimilationPDU.getMessageOffsets(); - - // iterate messages and stream into chunk - InputStream protocolInputStream = asapAssimilationPDU.getInputStream(); - Log.writeLog(this, this.toString(), "take data to local chunk or transient message: " + messagesContainer); - this.streamReceivedMessages2Container(messagesContainer, protocolInputStream, - messageOffsets, asapAssimilationPDU.getLength()); - - // add entry to hop list - List asapHopList = asapAssimilationPDU.getASAPHopList(); - Log.writeLog(this, this.toString(), "got hop list: " + asapHopList); - - // add this new hop - asapHopList.add(lastHop); - - // add hop list to newly create message container - messagesContainer.setASAPHopList(asapHopList); - - ////////////////// write log - String uri = asapAssimilationPDU.getChannelUri(); - // read all messages - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - if(listener != null) { - if(eraSender != ASAP.TRANSIENT_ERA) { - listener.chunkStored(this.format, - senderE2E, - uri, - eraSender, - asapHopList - ); - } else { - listener.transientMessagesReceived(transientMessages, lastHop); - } - - } else { - Log.writeLog(this, this.toString(), "no chunk assimilated listener found"); - } - } - private ASAPInternalChunk getIncomingChunk(String encounteredPeer, ASAP_AssimilationPDU_1_0 asapAssimilationPDU) - throws IOException, ASAPException { - - Log.writeLog(this, this.toString(), "called: get incoming chunk"); - String uri = asapAssimilationPDU.getChannelUri(); - int eraSender = asapAssimilationPDU.getEra(); - String senderE2E = asapAssimilationPDU.getSender(); - ASAPInternalStorage incomingStorage = (ASAPInternalStorage) this.getIncomingStorage(senderE2E, true); - ASAPChunkStorage incomingChunkStorage = incomingStorage.getChunkStorage(); - Log.writeLog(this, this.toString(), "got incoming chunk storage " - + incomingChunkStorage); - - // get local target for data to come - if (!incomingChunkStorage.existsChunk(uri, eraSender)) { - ASAPInternalChunk localChunk = null; - // is there a local chunk - to clone recipients from? - if (this.channelExists(uri)) { - Log.writeLog(this, this.toString(), "get local chunk to copy channel data"); - localChunk = incomingChunkStorage.getChunk(uri, this.getEra()); // get channel information - } else { // no information that can be copied - Log.writeLog(this, this.toString(), "asked to set up new channel: (uri/senderE2E): " - + uri + " | " + senderE2E); - // this channel is new to local peer - am I allowed to create it? - if (!this.securityAdministrator.allowedToCreateChannel(asapAssimilationPDU)) { - Log.writeLog(this, this.toString(), - ".. not allowed .. TODO not yet implemented .. always set up"); - - //allowedAssimilation = false; // TODO - } else { - Log.writeLog(this, this.toString(), "allowed. Set it up."); - this.createChannel(uri); - } - } - Log.writeLog(this, this.toString(), "create new chunk to assimilate received data"); - ASAPInternalChunk incomingChunk = incomingStorage.createNewChunk(uri, eraSender); - - if (localChunk != null) { - Log.writeLog(this, this.toString(), "copy local meta data into newly created incoming chunk"); - incomingChunk.copyMetaData(this.getChannel(uri)); - } - Log.writeLog(this, this.toString(), "new incoming chunk created: " + incomingChunk); - return incomingChunk; - } else { - // already exists. Add message if sender == originator and era last era of this channel - if(incomingStorage.getEra() == eraSender // era is current era - && PeerIDHelper.sameID(encounteredPeer, senderE2E) // E2E sender == P2P sender - ) { - Log.writeLog(this, this.toString(), - "received chunk exists but sender is originator and current era - message will be added: " - + senderE2E + " | " + eraSender + " | " + uri); - - // finish routing... - if(incomingChunkStorage.getChunk(uri, eraSender).getASAPHopList().size() > 1) { - throw new ASAPException("chunk was already routed to me - met originator - will no overwrite chunk"); - } - - return incomingChunkStorage.getChunk(uri, eraSender); - } else { - // read assimilation message payload to oblivion! - throw new ASAPException("chunk that already exists; not current era or not originator: " - + senderE2E + " | " + eraSender + " | " + uri); - } - } - } - - private void streamReceivedMessages2Container(MessagesContainer messagesContainer, - InputStream is, List messageOffsets, long totalLength) throws IOException { - - long offset = 0; - for (long nextOffset : messageOffsets) { - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - messagesContainer.addMessage(is, nextOffset - offset); - //if(!changed) { changed = true; this.contentChanged();} - offset = nextOffset; - } - - // last round - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - messagesContainer.addMessage(is, totalLength - offset); - } - - private boolean hasSufficientCrypto(ASAP_PDU_1_0 pdu) { - if(this.getCryptoControl() == null) { - Log.writeLog(this, this.toString(), "crypto control set to allow anything"); - return true; - } - - boolean proceed = this.getCryptoControl().allowed2Process(pdu); - if(!proceed) { - Log.writeLog(this, this.toString(), "no sufficient crypto: " + pdu); - } - - return proceed; - } - - public void handleASAPInterest(ASAP_Interest_PDU_1_0 asapInterest, ASAP_1_0 protocol, - String encounteredPeer, OutputStream os, ASAPEncounterConnectionType connectionType) - throws ASAPException, IOException { - - // before we start - lets crypto: TODO can be removed - do it on communication not engine level - if(!hasSufficientCrypto(asapInterest)) return; - - // get remote peer - String senderID = asapInterest.getSender(); - - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - // init - int workingEra = this.getOldestEra(); - - // already met? - if(this.lastSeen != null) { - Integer lastSeenEra = this.lastSeen.get(senderID); - if(lastSeenEra != null) workingEra = lastSeenEra; - } - - // got even information from other side? - Map encounterMap = asapInterest.getEncounterMap(); - Log.writeLog(this, this.toString(), "received encounterMap: " + encounterMap); - - // am I in encounter list? - if(encounterMap != null) { - Integer eraEncounteredMe = encounterMap.get(this.owner); - if(eraEncounteredMe != null) { - int eraEncounter = eraEncounteredMe; - Log.writeLog(this, this.toString(), "found me in encounter map: " + encounterMap); - // would start with next era - eraEncounter = ASAP.nextEra(eraEncounter); - if (eraEncounter != workingEra && ASAP.isEraInRange(eraEncounter, this.getOldestEra(), workingEra)) { - // this seems to be a valid era - maybe got routed data - Log.writeLog(this, this.toString(), - "change 1st era from " + workingEra + " to " + eraEncounter); - workingEra = eraEncounter; - } - } - } - - Log.writeLog(this, this.toString(), "transmit chunks from " + workingEra + " to era: " + this.era); - - if(workingEra == this.era) { - // nothing todo - b = new StringBuilder(); - b.append("there are no information before that era; "); - b.append("we only deliver information from previous eras - nothing todo here."); - Log.writeLog(this, this.toString(), b.toString()); - } else { - // we iterate up to era just before current one - current one is active sync. - int lastEra = this.getPreviousEra(this.era); - - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - // make a breakpoint here - if (this.memento != null) this.memento.save(this); - - this.sendChunks(this.owner, senderID, this.getChunkStorage(), protocol, workingEra, lastEra, os, true); - Log.writeLog(this, this.toString(), "ended iterating local chunks"); - } - - /////////////////////////////////// asap routing - - if(this.routingAllowed()) { - // iterate: what sender do we know in our side? - for(CharSequence receivedFromID : this.getSender()) { - if(PeerIDHelper.sameID(encounteredPeer, receivedFromID)) { - // do not send messages back - continue; - } - Log.writeLog(this, this.toString(), "going to route messages from " + receivedFromID); - try { - ASAPStorage receivedMessagesStorage = this.getExistingIncomingStorage(receivedFromID); - int eraLastToSend = receivedMessagesStorage.getEra(); - int eraFirstToSend = receivedMessagesStorage.getOldestEra(); - - // got encounter information from other peer? - if(encounterMap != null) { - Integer eraLastMet = encounterMap.get(receivedFromID); - if(eraLastMet != null) { - Log.writeLog(this, this.toString(), - "found sender received encounter map; last encounter: " + eraLastMet); - /* - Peer told us last encounter era - from senders perspective of course. - There are several options, sketch: - - <------ our storage -------> - ............ [eraFirst] +++++++++++++++ [eraLast] ......... - (a) (b) (c) (d) - a) We send everything we have - b) We send from b+1 until eraLast - c) + d) We are in sync or behind - nothing to do - */ - - // we would start with the next era - int eraAfterLastMet = ASAP.nextEra(eraLastMet); - - if(ASAP.isEraInRange(eraAfterLastMet, eraFirstToSend, eraLastToSend)) { // case b) - eraFirstToSend = eraAfterLastMet; - } - } - } - this.sendChunks(receivedFromID, senderID, receivedMessagesStorage.getChunkStorage(), protocol, - eraFirstToSend, eraLastToSend, os,false); - } - catch(ASAPException e) { - Log.writeLogErr(this, this.toString(), - "internal problem: we know sender but cannot access its storage"); - } - } - } else { - Log.writeLog(this, this.toString(), "engine does not send received chunks"); - } - } - - public boolean routingAllowed() { - return this.routingAllowed; - } - - public void setBehaviourAllowRouting(boolean on) throws IOException { - this.routingAllowed = on; - this.saveStatus(); - } - - void sendInterest(CharSequence ownerID, ASAP_1_0 protocol, OutputStream os) - throws IOException, ASAPException { - - Log.writeLog(this, this.toString(), "send interest for app/format: " + format); - - // produce encounter map - Map encounterMap = new HashMap<>(); - - Set encounteredPeers = this.lastSeen.keySet(); - for(String peerID : encounteredPeers) { - try { - int lastEra = this.getExistingIncomingStorage(peerID).getEra(); - encounterMap.put(peerID, lastEra); - } - catch(ASAPException e) { - /* - There is no storage for encountered peer. Can happen - met but has not got anything from it. - So, take era from last seen... - - I can't follow, sorry 2021, Dec, 10th (thsc42) - encounterMap.put(peerID, this.lastSeen.get(peerID)); - */ - } - } - Log.writeLog(this, this.toString(), "send encounterMap with interest: " + encounterMap); - - protocol.interest(ownerID, null, - format, null, ASAP_1_0.ERA_NOT_DEFINED, ASAP_1_0.ERA_NOT_DEFINED, - os, this.getASAPCommunicationCryptoSettings().mustSign(), - this.getASAPCommunicationCryptoSettings().mustEncrypt(), - this.routingAllowed(), - encounterMap); - } - - private void sendChunks(CharSequence sender, String encounteredPeer, ASAPChunkStorage chunkStorage, - ASAP_1_0 protocol, int workingEra, - int lastEra, OutputStream os, boolean remember) throws IOException, ASAPException { - Log.writeLog(this, this.toString(), - "sendChunks: sender: " + sender + " | encounteredPeer: " + encounteredPeer - + " | workingEra: " + workingEra); - - /* - There is a little challenge: era uses a circle of numbers - We cannot say: higher number, later era. That rule does *not* - apply. We can calculate next era, though. - - That loop has to be re-entered as long as working era has not - yet reached lastEra. In other words: lastRound is reached whenever - workingEra == lastEra. Processing lastEra is the last round - We at at least one round! - */ - - boolean lastRound = false; // assume more than one round - do { - lastRound = workingEra == lastEra; - - List chunks = chunkStorage.getChunks(workingEra); - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - for(ASAPInternalChunk chunk : chunks) { - boolean goAhead = true; // to avoid deep if-if-if-if structures - - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - - if(chunk.getLength() < 1) { - goAhead = false; - } - - // is not a public chunk - if (goAhead && !this.isPublic(chunk)) { - Set recipients = chunk.getRecipients(); - if (recipients == null || !recipients.contains(encounteredPeer)) { - goAhead = false; - } - } - - if (goAhead) { - Log.writeLog(this, this.toString(), "send chunk"); - protocol.assimilate(sender, // owner or source from received message - encounteredPeer, // peer to which we are connected right now - this.format, - chunk.getUri(), // channel ok - workingEra, // era ok - chunk.getLength(), // data length - chunk.getOffsetList(), - chunk.getASAPHopList(), - chunk.getMessageInputStream(), - os, - this.getASAPCommunicationCryptoSettings()); - - // remember sent - if(remember) chunk.deliveredTo(encounteredPeer); - Log.writeLog(this, this.toString(), "remembered delivered to " + encounteredPeer); - - //>>>>>>>>>>>>>>>>>>>debug - // sent to all recipients - if (chunk.getRecipients().size() == chunk.getDeliveredTo().size()) { - Log.writeLog(this, this.toString(), - "#recipients == #deliveredTo chunk delivered to any potential remotePeer - could drop it"); - if (this.isDropDeliveredChunks()) { - chunk.drop(); - Log.writeLog(this, this.toString(), "chunk dropped"); - } else { - Log.writeLog(this, this.toString(), - "drop flag set false - engine does not remove delivered chunks"); - } - } - } else { - Log.writeLog(this, this.toString(), "nothing sent: empty or not on recipient list"); - } - } - - if(remember) { - // remember that we are in sync until that era - this.setLastSeen(encounteredPeer, workingEra); - - // make a breakpoint here - if (this.memento != null) this.memento.save(this); - } - - // next era which isn't necessarily workingEra++ - workingEra = this.getNextEra(workingEra); - - // as long as not already performed last round - } while(!lastRound); - } - - private boolean isDropDeliveredChunks() { - return this.dropDeliveredChunks; - } - - public void setBehaviourDropDeliveredChunks(boolean drop) throws IOException { - this.dropDeliveredChunks = drop; - this.saveStatus(); - } - - @Override - public int getNextEra(int workingEra) { - return ASAP.nextEra(workingEra); - } - - @Override - public int getPreviousEra(int workingEra) { - return ASAP.previousEra(workingEra); - } - - private int getEraStartSync(String peer) { - Integer lastEra = this.lastSeen.get(peer); - if(lastEra == null) { - return this.getOldestEra(); - } - - return lastEra; - } - - private void setLastSeen(String peer, int workingEra) { - this.lastSeen.put(peer, era); - } - - @Override - public int getOldestEra() { - return this.oldestEra; - } - - @Override - public int getEra() { - return this.era; - } - - @Override - public CharSequence getFormat() { - return this.format; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Online management // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public void activateOnlineMessages(ASAPInternalPeer multiEngine) { - if(this.asapOnlineMessageSender == null) { - Log.writeLog(this, this.toString(), - "(" + this.format + ") created new online message sender"); - this.attachASAPMessageAddListener(new ASAPOnlineMessageSenderEngineSide(multiEngine)); - } else { - Log.writeLog(this, this.toString(), - "(" + this.format + ") online message sender already running"); - } - } - - public void deactivateOnlineMessages() { - this.detachASAPMessageAddListener(); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPEngineFS.java b/src/main/java/net/sharksystem/asap/engine/ASAPEngineFS.java deleted file mode 100644 index 142a4fa..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPEngineFS.java +++ /dev/null @@ -1,296 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPChannel; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.utils.Log; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * ASAPEngine that stores data in file system. - * @author thsc - */ -public class ASAPEngineFS extends ASAPEngine { - public static final String MEMENTO_FILENAME = "asapCurrentAttributes"; - private final String rootDirectory; - - public static final String DEFAULT_ROOT_FOLDER_NAME = "SHARKSYSTEM_ASAP"; - - private ASAPEngineFS(String owner, String rootDirectory, CharSequence format) - throws ASAPException, IOException { - - super(new ASAPChunkStorageFS(rootDirectory, format.toString()), format); - - this.owner = owner; - this.rootDirectory = rootDirectory; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("owner: "); - sb.append(this.getOwner()); - sb.append(" | oldestEra: "); - sb.append(this.getOldestEra()); - sb.append(" | era: "); - sb.append(this.getEra()); - sb.append(" | routing: "); - sb.append(this.routingAllowed()); - /* - sb.append(" | rootFolder: "); - sb.append(this.rootDirectory); - */ - - return sb.toString(); - } - - public String getRootFolder() { - return this.rootDirectory; - } - - public String getOwner() { - return this.owner; - } - - public static ASAPEngine getASAPStorage(String owner, String rootDirectory, CharSequence format) - throws IOException, ASAPException { - - return ASAPEngineFS.getASAPEngine(owner, rootDirectory, format); - } - - public static ASAPEngine getExistingASAPEngineFS(String rootDirectory) - throws IOException, ASAPException { - - // the same - return ASAPEngineFS.getASAPEngineFS(null, rootDirectory, null); - } - - /** - * get / create engine - * @param owner - * @param rootDirectory - * @param format - * @return - * @throws IOException - * @throws ASAPException - */ - public static ASAPEngine getASAPEngine(String owner, String rootDirectory, CharSequence format) - throws IOException, ASAPException { - - // check if root directory already exists. If not set it up - File root = new File(rootDirectory); - if(!root.exists()) { - root.mkdirs(); - } - - return ASAPEngineFS.getASAPEngineFS(owner, rootDirectory, format); - } - - public ASAPInternalStorage refresh() throws IOException, ASAPException { - this.memento.save(this); - return ASAPEngineFS.getExistingASAPEngineFS(this.rootDirectory); - } - - public void setOldestEra(int oldestEra) throws IOException { - this.oldestEra = oldestEra; - this.saveMemento(); - } - - private void saveMemento() throws IOException { - this.getMemento(this.rootDirectory).save(this); - } - - static ASAPEngineFS getASAPEngineFS(String owner, String rootDirectory, CharSequence format) - throws IOException, ASAPException { - return ASAPEngineFS.getASAPEngineFS(owner, rootDirectory, format, false); - } - - /** - * - * @param owner can be null - restored - * @param rootDirectory must not be null - * @param format can be null - restored - * @return - * @throws IOException - * @throws ASAPException - */ - static ASAPEngineFS getASAPEngineFS(String owner, String rootDirectory, CharSequence format, boolean createFolder) - throws IOException, ASAPException { - - // root directory must exist when setting up an engine - File root = new File(rootDirectory); - if(!root.exists() || !root.isDirectory()) { - if(!createFolder) { - throw new ASAPException("chunk root directory must exist when creating an ASAPEngine: " + rootDirectory); - } else { - root.mkdirs(); - } - } - - if(format == null || format.toString().equalsIgnoreCase(ASAP_1_0.ANY_FORMAT)) { - ASAPMementoFS asapMementoFS = new ASAPMementoFS(root); - asapMementoFS.read(); - format = asapMementoFS.getFormat(); - } - - String formatString = format != null ? format.toString() : ASAP_1_0.ANY_FORMAT; - ASAPEngineFS engine = new ASAPEngineFS( - owner, - rootDirectory, -// new ASAPChunkStorageFS(rootDirectory, formatString), -// ASAP_1_0.ANY_FORMAT // set to default - real value is restored by memento anyway - formatString - - ); - - - ASAPMementoFS mementoFS = engine.getMemento(rootDirectory); - engine.memento = mementoFS; - - mementoFS.restore(engine); - - if(format != null) { - // overwrite default - actually set format - if(engine.format.equalsIgnoreCase(ASAP_1_0.ANY_FORMAT.toString())) { - engine.format = format.toString(); - } - else { // cannot overwrite a non-default format - if(!format.toString().equalsIgnoreCase(engine.format)) { - throw new ASAPException("cannot overwrite existing format (" + format + "with another one: (" - + engine.format + ")"); - } - } - } - - // replacing owner could be done - if(owner != null - && !owner.equalsIgnoreCase(ANONYMOUS_OWNER) - && !owner.equalsIgnoreCase(DEFAULT_OWNER) - ) { - engine.owner = owner; - } - - // save changes - mementoFS.save(engine); - - return engine; - } - - private void restoreFromMemento() throws IOException { - ASAPMementoFS mementoFS = this.getMemento(rootDirectory); - this.memento = mementoFS; - - mementoFS.restore(this); - - } - - void syncMemento() throws IOException { - ASAPMementoFS asapMementoFS = new ASAPMementoFS(new File(this.rootDirectory)); - asapMementoFS.read(); -// Log.writeLog(this, this.toString(), "read memento: " + asapMementoFS); -// Log.writeLog(this, this.toString(), "this.lastwritten: " + this.lastMementoWritten); - - if(asapMementoFS.lastMementoWritten != this.lastMementoWritten) { -// Log.writeLog(this, this.toString(),"restore from memento - out of sync"); - this.restoreFromMemento(); - } - } - - @Override - public void add(CharSequence uri, byte[] messageAsBytes) throws IOException { - // always re-read metainformation - this.restoreFromMemento(); - - // do the real work - super.add(uri, messageAsBytes); - } - - /* - public static ASAPEngine getASAPEngine(String rootDirectory, CharSequence format) - throws IOException, ASAPException { - - return ASAPEngineFS.getASAPEngine(null, rootDirectory, format); - - }*/ - - private ASAPMementoFS getMemento(String rootDirectory) { - return new ASAPMementoFS(new File(rootDirectory)); - } - - private HashMap storageList = new HashMap<>(); - - @Override - public ASAPChunkStorage getReceivedChunksStorage(CharSequence sender) { - String dir = this.rootDirectory + "/" + sender; - return new ASAPChunkStorageFS(dir, this.format, this.era); - } - - public ASAPInternalStorage getIncomingStorage(CharSequence sender, boolean create) throws IOException, ASAPException { - return ASAPEngineFS.getASAPEngineFS( - sender.toString(), // becomes owner - this.rootDirectory + "/" + sender, // folder - this.getFormat(), // format taken from superior storage - create); - } - - public ASAPInternalStorage getExistingIncomingStorage(CharSequence sender) throws IOException, ASAPException { - return this.getIncomingStorage(sender, true); - } - - /** - * Backdoor - for tests only - create an incoming storage - * @param sender - * @return - * @throws IOException - * @throws ASAPException - */ - public ASAPInternalStorage getIncomingStorage(CharSequence sender) throws IOException, ASAPException { - return this.getIncomingStorage(sender, true); - /* - String folderName = this.rootDirectory + "/" + sender; - File folder = new File(folderName); - if(!folder.exists()) { - folder.mkdirs(); - } - - return ASAPEngineFS.getASAPEngineFS( - sender.toString(), // becomes owner - folderName, // folder - this.getFormat()); // format taken from superior storage - */ - } - - @Override - public List getSender() { - List senderList = new ArrayList<>(); - - File dir = new File(this.rootDirectory); - - String[] dirEntries = dir.list(); - - if (dirEntries != null) { - for (String fileName : dirEntries) { - // era folder? - try { - Integer.parseInt(fileName); - // a number. It is a era folder go ahead - continue; - } catch (NumberFormatException e) { - // no number - that's ok! - } - - File fileInDir = new File(this.rootDirectory + "/" + fileName); - if (fileInDir.isDirectory()) { - senderList.add(fileName); - } - } - } - - return senderList; - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPEngineFSSetting.java b/src/main/java/net/sharksystem/asap/engine/ASAPEngineFSSetting.java deleted file mode 100644 index f2fe8cf..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPEngineFSSetting.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.sharksystem.asap.engine; - -public class ASAPEngineFSSetting { - final CharSequence folder; - final CharSequence format; - final ASAPChunkAssimilatedListener listener; - - public ASAPEngineFSSetting(CharSequence format, CharSequence folder, - ASAPChunkAssimilatedListener listener) { - this.format = format; - this.folder = folder; - this.listener = listener; - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPEnginePermissionSettings.java b/src/main/java/net/sharksystem/asap/engine/ASAPEnginePermissionSettings.java deleted file mode 100644 index 2679c4e..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPEnginePermissionSettings.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.IOException; - -interface ASAPEnginePermissionSettings { - /** - * Engine can remember peers they encountered. It is assumed that those peers are kept with the local peer (not only - * in this engine) - * @param on - * @throws IOException - */ - void setRememberEncounteredPeers(boolean on) throws IOException; - - /** - * Engine would ignore all unencrypted messages if set true. - * @param on - * @throws IOException - */ - void setReceivedMessagesMustBeEncrypted(boolean on) throws IOException; - - /** - * Engine would ignore all unsigned messages if set true. - * @param on - * @throws IOException - */ - void setReceivedMessagesMustBeSigned(boolean on) throws IOException; - - /** - * Define with what peers an engine is allowed to communicate - * @param safetyLevel - * @throws IOException - */ - void setSetAllowedRemotePeers(AllowedRemotePeers safetyLevel); - - public enum AllowedRemotePeers { - ANY_PEER /** no restrictions - allowed to communicate with any peer */, - PEERS_MET /** allowed to communicate with already encountered peers */, - PEERS_VERIFIED /** allowed to communicate with peers who can be verified with a certificate */; - } - - /** - * Engine is allowed to reveal its supported format or not - * @param peerName can be null for anonymous peer - * @return - */ - boolean setRevealEngineFormat(String peerName); - - /** - * Engine is allowed to send open (messages with no recipient specified) messages to a peer - * @param peerName can be null for anonymous peer - * @return - */ - boolean setSendOpenMessages(String peerName); -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInMemoMessages.java b/src/main/java/net/sharksystem/asap/engine/ASAPInMemoMessages.java deleted file mode 100644 index 7162d0b..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInMemoMessages.java +++ /dev/null @@ -1,384 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPUtils; -import net.sharksystem.utils.Utils; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.*; - -/** - * @author thsc - */ -class ASAPInMemoMessages implements ASAPMessages { - public static final int DEFAULT_MAX_CACHE_SIZE = 1000; - private final CharSequence uri; - private final ASAPChunkStorageFS chunkStorage; - private final int fromEra; - private final int toEra; - private final String format; - - private List chunkList; - - /** the internal message Cache */ - private List messageCache; - private int firstIndexMessageCache = -1; - private int lastIndexMessageCache = -1; - private int maxCacheLen; - - private int numberOfMessages = 0; - - public ASAPInMemoMessages(ASAPChunkStorageFS chunkStorage, - String format, CharSequence uri, int fromEra, int toEra, int maxCacheLen) { - - this.format = format; - this.uri = uri; - this.chunkStorage = chunkStorage; - this.fromEra = fromEra; - this.toEra = toEra; - this.maxCacheLen = maxCacheLen; - - Log.writeLog(this, this.toString()); - } - - public String toString() { - return "format: " - + format - + " | uri: " + uri - + " | fromEra: " + fromEra - + " | toEra: " + toEra - + " | rootDir: " + chunkStorage.getRootDirectory(); - } - - public ASAPInMemoMessages(ASAPChunkStorageFS chunkStorage, - String format, CharSequence uri, int fromEra, int toEra) { - - this(chunkStorage, format, uri, fromEra, toEra, DEFAULT_MAX_CACHE_SIZE); - } - - private boolean initialized = false; - - private void initialize() throws IOException { - if(!initialized) { - this.syncChunkList(); - this.initialized = true; - } - } - - private void syncChunkList() throws IOException { - // get all chunks in chronological order - Collection erasInFolder = Utils.getErasInFolder(this.chunkStorage.getRootDirectory()); - if(erasInFolder.isEmpty()) return; - - Collection erasToUse = ASAPUtils.getErasInRange(erasInFolder, this.fromEra, this.toEra); - if(erasToUse.isEmpty()) return; - - /* - // current era in following loop - int thisEra = this.fromEra; - - // do we need more than one loop? - boolean anotherLoop = this.fromEra != this.toEra; - - // are we in the final loop? - boolean finalLoop = !anotherLoop; - */ - - // drop old chunk list - if any - this.chunkList = new ArrayList<>(); - -// do { - for(Integer thisEra : erasToUse) { - // check if chunk exists - don't create on - Log.writeLog(this, "reached era: " + thisEra); - if (erasInFolder.contains(thisEra) && this.chunkStorage.existsChunk(this.uri, thisEra)) { - // is there - get it - Log.writeLog(this, "getChunk with era: " + thisEra); - ASAPInternalChunk chunk = this.chunkStorage.getChunk(this.uri, thisEra); - this.chunkList.add(chunk); - this.numberOfMessages += chunk.getNumberMessage(); - } - - /* - if (anotherLoop) { - if (finalLoop) { - anotherLoop = false; - } else { - thisEra = ASAP.nextEra(thisEra); - finalLoop = thisEra == this.toEra; - } - } - } while (anotherLoop); - */ - } - } - - public int size() throws IOException { - this.initialize(); - return this.numberOfMessages; - } - - @Override - public CharSequence getURI() { - return this.uri; - } - - @Override - public CharSequence getFormat() { - return this.format; - } - - public Iterator getMessagesAsCharSequence() throws IOException { - this.initialize(); - - return new ChunkListMessageIterator(this.chunkList); - } - - @Override - public Iterator getMessages() throws IOException { - this.initialize(); - - return new ChunkListByteMessageIterator(this.chunkList); - } - - @Override - public CharSequence getMessageAsCharSequence(int position, boolean chronologically) throws ASAPException, IOException { - return new String(this.getMessage(position, chronologically)); - } - - public ASAPInternalChunk getChunk(int position, boolean chronologically) throws IOException, ASAPException { - this.initialize(); - - if(position >= this.numberOfMessages) - throw new ASAPException("Position reaches beyond total number of messages in this chunk (is it even empty?)"); - - if(!chronologically) { - // invert position - first becomes last etc. - position = this.numberOfMessages - 1 - position; - } - - ASAPInternalChunk foundChunk = null; - // find chunk - for(ASAPInternalChunk chunk : this.chunkList) { - if(position < chunk.getNumberMessage()) { - foundChunk = chunk; - break; - } - - position -= chunk.getNumberMessage(); - } - - if(foundChunk == null) throw new ASAPException("cannot find chunk for position - looks like a bug"); - return foundChunk; - } - - @Override - public byte[] getMessage(int position, boolean chronologically) - throws ASAPException, IOException { - - this.initialize(); - - if(position >= this.numberOfMessages) - throw new ASAPException("Position reaches beyond total number of messages in this chunk (is it even empty?)"); - - if(!chronologically) { - // invert position - first becomes last etc. - position = this.numberOfMessages - 1 - position; - } - - if(this.messageCache != null && position >= this.firstIndexMessageCache && position <= this.lastIndexMessageCache) { - return this.messageCache.get(position - this.firstIndexMessageCache); - } - - // not yet in cache - find chunk with required message - int firstIndex = 0; // absolut index of first message in current chunk - int lastIndex = 0; // absolut index of last message in current chunk - - boolean found = false; - ASAPInternalChunk fittingChunk = null; - int fittingChunkIndex = 0; - - for(ASAPInternalChunk chunk : this.chunkList) { - lastIndex = firstIndex + chunk.getNumberMessage() - 1; - - if(position >= firstIndex && position <= lastIndex) { - // we have got our chunk - fittingChunk = chunk; - break; - } - - firstIndex += chunk.getNumberMessage(); - fittingChunkIndex++; - } - - if(fittingChunk == null) { - throw new ASAPException("internal failure - wrong calculation in chunk cache"); - } - - // we can fill our cache right now - - // reset cache - this.messageCache = new ArrayList<>(); - - ///////////////////////////////////////////////////////////////// - // simple approach in that first implementation ... we keep fitting chunk in memory - ///////////////////////////////////////////////////////////////// - -// Iterator messages = fittingChunk.getMessagesAsCharSequence(); - Iterator messages = fittingChunk.getMessages(); - - // chunk bigger than max cache size? - int chunkSize = fittingChunk.getNumberMessage(); - if(chunkSize > this.maxCacheLen) { - // calculate how many messages to skip before caching - - /* - situation: - chunk head |................position...........................| tail - cache head |................| tail - - solution: put position in middle of the cache - chunk |................position...........................| - planned cache |........position........| - skipLen...| - */ - - int skipLen = position - (this.maxCacheLen / 2); - - // first index in cache will be this one: - firstIndex += skipLen; - - // skip - for(;skipLen > 0; skipLen--) { - this.messageCache.add(messages.next()); - } - } - - this.firstIndexMessageCache = firstIndex; - - int counter = 0; - while(messages.hasNext()) { - this.messageCache.add(messages.next()); - counter++; - if(counter > this.maxCacheLen) break; - } - - this.lastIndexMessageCache = this.firstIndexMessageCache + counter - 1; - - // cache filled - call again - /* not: it is always chronologically true!! - a) we already came in with true -> it remains true - b) we came with false -> we have already recalculated that position, we would - move it around again with that call - keep position unchanged: true! - */ - - return this.getMessage(position, true); - } - - public void sync() throws IOException { - this.initialized = false; - this.firstIndexMessageCache = -1; - this.lastIndexMessageCache = -1; - this.numberOfMessages = 0; - this.messageCache = null; - } - - ////////////////////////////////////////////////////////////////////////////////////////// - // helper: message iterator implementation // - ////////////////////////////////////////////////////////////////////////////////////////// - - private abstract class ChunkListIterator { - private final List chunkList; - private ASAPInternalChunk currentChunk; - private int nextIndex; - private Iterator currentIterator; - private T messageAhead; - - public ChunkListIterator(List chunkList) throws IOException { - this.chunkList = chunkList; - this.currentChunk = null; - this.nextIndex = 0; - this.messageAhead = null; // mark as empty - this.readAhead(); // init cache - } - - /** - * read next message in field messageAhead. - */ - private void readAhead() { - if (this.currentIterator != null) { - if (this.currentIterator.hasNext()) { - // 'normal' case: we read next message - this.messageAhead = this.currentIterator.next(); - return; // done - } - } - // no more messages in that iterator / chunk - if (this.chunkList == null || nextIndex >= this.chunkList.size() ) { - return; // there is no list at all or we are already through with it - } - - // open next chunk / iterator - this.currentChunk = this.chunkList.get(this.nextIndex++); - try { - this.currentIterator = this.getMessageIterator(currentChunk); - this.readAhead(); // next try - } catch (IOException e) { - // cannot recover from that problem - return; - } - } - - - public boolean hasNext() { - return this.messageAhead != null; - } - - public T next() { - if(this.messageAhead == null) { - throw new NoSuchElementException("list empty or already reached end"); - } - - // remove that single message cache - T retMessage = this.messageAhead; - this.messageAhead = null; - - // read ahead - if possible - this.readAhead(); - - return retMessage; - } - - abstract Iterator getMessageIterator(ASAPInternalChunk chunk) throws IOException; - } - - private class ChunkListMessageIterator extends ChunkListIterator implements Iterator { - private Iterator currentIterator; - private CharSequence messageAhead; - - public ChunkListMessageIterator(List chunkList) throws IOException { - super(chunkList); - } - - @Override - Iterator getMessageIterator(ASAPInternalChunk chunk) throws IOException { - return chunk.getMessagesAsCharSequence(); - } - } - - private class ChunkListByteMessageIterator extends ChunkListIterator implements Iterator { - private Iterator currentIterator; - private CharSequence messageAhead; - - public ChunkListByteMessageIterator(List chunkList) throws IOException { - super(chunkList); - } - - @Override - Iterator getMessageIterator(ASAPInternalChunk chunk) throws IOException { - return chunk.getMessages(); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInMemoTransientMessages.java b/src/main/java/net/sharksystem/asap/engine/ASAPInMemoTransientMessages.java deleted file mode 100644 index 10d1642..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInMemoTransientMessages.java +++ /dev/null @@ -1,101 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.*; -import net.sharksystem.asap.protocol.ASAP_AssimilationPDU_1_0; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class ASAPInMemoTransientMessages implements ASAPMessages, MessagesContainer { - private final CharSequence format; - private final CharSequence uri; - private final CharSequence sender; - private ASAPHop asapHop; - private int size = -1; - private List messageList = new ArrayList<>(); - - ASAPInMemoTransientMessages(ASAP_AssimilationPDU_1_0 pdu, ASAPHop asapHop) { - this.format = pdu.getFormat(); - this.uri = pdu.getChannelUri(); - this.sender = pdu.getSender(); - this.asapHop = asapHop; - } - - public ASAPInMemoTransientMessages(CharSequence format, CharSequence uri, CharSequence sender, ASAPHop asapHop) { - this.format = format; - this.uri = uri; - this.sender = sender; - this.asapHop = asapHop; - } - - @Override - public int size() throws IOException { - return this.messageList.size(); - } - - @Override - public CharSequence getURI() { - return this.uri; - } - - @Override - public CharSequence getFormat() { - return this.format; - } - - public CharSequence getSender() { return this.sender; } - - @Override - public void setASAPHopList(List asapHopList) throws IOException { - if(this.asapHop == null) { - this.asapHop = asapHopList.get(asapHopList.size()-1); - } - } - - @Override - public Iterator getMessagesAsCharSequence() throws IOException { - throw new IOException("not implemented yet"); - } - - @Override - public Iterator getMessages() throws IOException { - return this.messageList.iterator(); - } - - @Override - public CharSequence getMessageAsCharSequence(int position, boolean chronologically) throws ASAPException, IOException { - return new String(this.getMessage(position, chronologically)); - } - - @Override - public byte[] getMessage(int position, boolean chronologically) throws ASAPException, IOException { - if(position > this.messageList.size() || position < 0) - throw new ASAPException("no message on index (out of range): " + position); - - int index = chronologically ? position : this.messageList.size() - position; - - return this.messageList.get(index); - } - - @Override - public ASAPChunk getChunk(int position, boolean chronologically) throws IOException, ASAPException { - throw new ASAPException("transient message are not stored"); - } - - @Override - public void addMessage(InputStream is, long length) throws IOException { - if(length > Integer.MAX_VALUE) throw new IOException("length exceeds range of integer value"); - - byte[] message = new byte[(int)length]; - is.read(message); - - this.addMessage(message); - } - - public void addMessage(byte[] message) throws IOException { - this.messageList.add(message); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunk.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunk.java deleted file mode 100644 index 39c794e..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunk.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPChannel; -import net.sharksystem.asap.ASAPChunk; -import net.sharksystem.asap.ASAPHop; - -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -/** - * An ASAP chunk is a set of message with the same format, same uri and same era. - * - * Reading from a chunk can be done anytime. - * - * Use change methods only if you really know what you do. Most likely, there will be - * a running ASAP protocol in the background that writes data into chunks, namely chunks - * of current era. The protocol engine reads also from older era to transmit messages to - * encountered peers. There will be a documentation that explains strategies when to do what. - * - * Rule of thumb: Read is ok. Better do not change anything with this interface. - * - * @author thsc - */ -public interface ASAPInternalChunk extends ASAPChunk, MessagesContainer { - /** - * Convenient methode: It calls getMessages and transforms each message into a string - * @return iterator of all messages in the chunk - * @throws IOException - */ - Iterator getMessagesAsCharSequence() throws IOException; - - /** - * - * @return recipients of that chunk - */ - Set getRecipients(); - - /** - * add recipients - * @param recipient - * @throws IOException - */ - void addRecipient(CharSequence recipient) throws IOException; - - /** - * set a list of recipients. Former recipients are dikscarded - * @param recipients - * @throws IOException - */ - void setRecipients(Collection recipients) throws IOException; - - /** - * recipient is removed - * @param recipients - * @throws IOException - */ - void removeRecipient(CharSequence recipients) throws IOException; - - long getLength(); - - List getOffsetList(); - - InputStream getMessageInputStream(); - - void putExtra(String key, String value) throws IOException; - - CharSequence removeExtra(String key) throws IOException; - - CharSequence getExtra(String key) throws IOException; - - /** - * set up this chunk by a source - * @param chunkSource - */ - void clone(ASAPInternalChunk chunkSource) throws IOException; - - HashMap getExtraData(); - - void deliveredTo(String peer) throws IOException; - - List getDeliveredTo(); - - void copyMetaData(ASAPChannel channel) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunkFS.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunkFS.java deleted file mode 100644 index 7e57eaa..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalChunkFS.java +++ /dev/null @@ -1,534 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPChannel; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.asap.utils.ASAPLogHelper; -import net.sharksystem.utils.Log; -import net.sharksystem.utils.SerializationHelper; - -import java.io.*; -import java.util.*; - -/** - * - * @author thsc - */ -public class ASAPInternalChunkFS implements ASAPInternalChunk { - public static final String META_DATA_EXTENSION = "meta"; - public static final String DATA_EXTENSION = "content"; - public static final String DEFAULT_URL = "content://sharksystem.net/noContext"; - private final ASAPChunkStorageFS storage; - private String sender; - private String uri = DEFAULT_URL; - private Set recipients; - private List deliveredTo; - private List messageStartOffsets = new ArrayList<>(); - private File metaFile; - private File messageFile; - - private List hopList; - - private int era; - - private HashMap extraData = new HashMap<>(); - - - @Override - public void clone(ASAPInternalChunk chunkSource) throws IOException { - if(metaFile.getAbsolutePath().contains("ultihopTests/Alice_42/1/sha")) { - Log.writeLog(this, this.toString(), "DEBUGGING_Multihop_Bug #2: " + metaFile.exists()); - } - - this.uri = chunkSource.getUri(); - this.recipients = chunkSource.getRecipients(); - this.extraData = chunkSource.getExtraData(); - - this.saveStatus(); - } - - @Override - public void copyMetaData(ASAPChannel channel) throws IOException { - this.uri = channel.getUri().toString(); - this.recipients = channel.getRecipients(); - this.extraData = channel.getExtraData(); - - this.saveStatus(); - } - - @Override - public List getASAPHopList() { - return this.hopList; - } - - public void setASAPHopList(List asapHopList) throws IOException { - this.hopList = asapHopList; - this.saveStatus(); - } - - public HashMap getExtraData() { - return this.extraData; - } - - @Override - public void deliveredTo(String peer) throws IOException { - this.deliveredTo.add(peer); - this.saveStatus(); - } - - @Override - public List getDeliveredTo() { - return this.deliveredTo; - } - - ASAPInternalChunkFS(ASAPChunkStorageFS storage, String uri, int era) throws IOException { - this(storage, uri, era, null); - } - - ASAPInternalChunkFS(ASAPChunkStorageFS storage, String uri, int era, String sender) throws IOException { - this.storage = storage; - if(uri != null) { - this.uri = uri; - } - this.era = era; - this.sender = sender; - - //Log.writeLog(this, this.toString(), "construct chunkFS"); - String trunkName = this.storage.setupChunkFolder(era, uri); - - // init - this.initFiles(trunkName); - } - - public ASAPInternalChunkFS(ASAPChunkStorageFS storage, String trunkName) throws IOException { - this.storage = storage; - this.uri = ASAPInternalChunkFS.DEFAULT_URL; - - this.initFiles(trunkName); - } - - private void initFiles(String trunkName) throws IOException { - String messageFileName = trunkName + "." + DATA_EXTENSION; - String metaFileName = trunkName + "." + META_DATA_EXTENSION; - - this.messageFile = new File(messageFileName); - this.metaFile = new File(metaFileName); - - // init meta file - message file keeps untouched (good idea?) - if(!this.metaFile.exists()) { - Log.writeLog(this, "meta file does not exist / set up: " + this.metaFile); - if(!this.metaFile.getParentFile().exists()) { - this.metaFile.getParentFile().mkdirs(); - //Log.writeLog(this, "parent folder created: " + this.messageFile.getParentFile().exists()); - } - this.metaFile.createNewFile(); - } else { - Log.writeLog(this, "meta file does already exists: " + this.metaFile); - } - - // try to read existing meta data - if(!this.readMetaData(this.metaFile)) { - // no meta date to be read - set defaults - this.writeMetaData(this.metaFile); - this.recipients = new HashSet<>(); - this.deliveredTo = new ArrayList<>(); - this.messageStartOffsets = new ArrayList<>(); - this.hopList = new ArrayList<>(); - } - } - - private void saveStatus() throws IOException { - this.writeMetaData(this.metaFile); - } - - @Override - public Set getRecipients() { - return this.recipients; - } - - @Override - public void addRecipient(CharSequence recipient) throws IOException { - this.recipients.add(recipient); - this.writeMetaData(this.metaFile); - } - - @Override - public void setRecipients(Collection newRecipients) throws IOException { - this.recipients = new HashSet<>(); - if(recipients != null) { - for (CharSequence recipient : newRecipients) { - this.recipients.add(recipient); - } - } - - this.writeMetaData(this.metaFile); - } - - @Override - public void removeRecipient(CharSequence recipient) throws IOException { - this.recipients.remove(recipient); - this.writeMetaData(this.metaFile); - } - - @Override - public String getUri() { - return (String) this.uri; - } - - /* - @Override - public void addMessage(CharSequence message) throws IOException { - this.addMessage(message.toString().getBytes()); - } -*/ - @Override - public void addMessage(byte[] messageAsBytes) throws IOException { - if(messageAsBytes.length > Integer.MAX_VALUE) { - throw new IOException("message must not be longer than Integer.MAXVALUE"); - } - - InputStream is = new ByteArrayInputStream(messageAsBytes); - - this.addMessage(is, messageAsBytes.length); - } - - public void addMessage(InputStream messageByteIS, long length) throws IOException { - //Log.writeLog(this, "going to add message to chunkFS" ); - if(length > Integer.MAX_VALUE) { - throw new IOException("message must not be longer than Integer.MAXVALUE"); - } - - long offset = 0; - if(!this.messageFile.exists()) { - if(!this.messageFile.getParentFile().exists()) { - this.messageFile.getParentFile().mkdirs(); - Log.writeLog(this, "parent folder created: " + this.messageFile.getParentFile().exists()); - } - this.messageFile.createNewFile(); - } else { - offset = this.messageFile.length(); - } - //Log.writeLog(this, "got chunk content file length: " + offset); - - OutputStream os = new FileOutputStream(this.messageFile, true); - //Log.writeLog(this, "opened chunk content file to append data"); - - //Log.writeLog(this, "write message to the end of chunk file"); - while(length-- > 0) { - os.write(messageByteIS.read()); - } - - //Log.writeLog(this, "closing"); - os.close(); - - // remember offset if not 0 - if(offset > 0) { - this.messageStartOffsets.add(offset); - this.saveStatus(); - } - } - - @Override - public Iterator getMessages() throws IOException { - return this.getMessagesAsBytesList().iterator(); - } - - private List getMessagesAsBytesList() throws IOException { - List byteMessageList = new ArrayList<>(); - - if(this.messageFile.length() > 0) { - InputStream is = new FileInputStream((this.messageFile)); - long offset = 0; - for(Long nextOffset : this.messageStartOffsets) { - long messageLenLong = nextOffset.longValue() - offset; - if(messageLenLong > Integer.MAX_VALUE) { - throw new IOException("message longer than Integer.MAXVALUE"); - } - - int messageLen = (int) messageLenLong; - byte[] messageBytes = new byte[messageLen]; - - is.read(messageBytes); - - byteMessageList.add(messageBytes); - - offset = nextOffset; - } - - // read last one - long messageLenLong = this.messageFile.length() - offset; - if(messageLenLong > Integer.MAX_VALUE) { - throw new IOException("message longer than Integer.MAXVALUE"); - } - - int messageLen = (int) messageLenLong; - byte[] messageBytes = new byte[messageLen]; - is.read(messageBytes); - byteMessageList.add(messageBytes); - } - - return byteMessageList; - } - - public long getLength() { - return this.messageFile.length(); - } - - @Override - public List getOffsetList() { - return this.messageStartOffsets; - } - - @Override - public InputStream getMessageInputStream() { - InputStream is = null; - try { - is = new FileInputStream(this.messageFile); - } catch (FileNotFoundException e) { - // cannot happen - is checked before - } - - return is; - } - - @Override - public void putExtra(String key, String value) throws IOException { - if(key == null || value == null) { - throw new IOException("null values are not allowed in extra data"); - } - this.extraData.put(key, value); - this.saveStatus(); - } - - @Override - public CharSequence removeExtra(String key) throws IOException { - if(key == null) throw new IOException("null key not allowed"); - String removed = this.extraData.remove(key); - this.saveStatus(); - return removed; - } - - @Override - public CharSequence getExtra(String key) throws IOException { - if(key == null) throw new IOException("null key not allowed"); - return this.extraData.get(key); - // no status change - } - - @Override - public Iterator getMessagesAsCharSequence() throws IOException { - try { - return new MessageIter(this.getMessagesAsBytesList()); - } catch (FileNotFoundException ex) { - throw new IOException(ex.getLocalizedMessage()); - } - } - - @Override - public void drop() { - this.metaFile.delete(); - this.messageFile.delete(); - } - - private boolean readMetaData(File metaFile) throws IOException { - if(!metaFile.exists()) return false; - // read data from metafile - DataInputStream dis = new DataInputStream(new FileInputStream(metaFile)); - - try { - // do it as first element - shure how many bytes we read.. - this.hopList = ASAPSerialization.readASAPHopList(dis); - - this.uri = dis.readUTF(); - this.setExtraByString(dis.readUTF()); - } - catch(EOFException | ASAPException eof) { - // file empty - return false; - } - - try { - this.recipients = SerializationHelper.string2CharSequenceSet(dis.readUTF()); - this.deliveredTo = SerializationHelper.string2CharSequenceList(dis.readUTF()); - - // finally read offset list - String offsetList = dis.readUTF(); - this.messageStartOffsets = this.messageOffsetString2List(offsetList); - } - catch(IOException e) { - // no more data - ok - } finally { - dis.close(); - } - - return true; - } - - private void writeMetaData(File file2writeMetaData) throws IOException { - // write data to metafile - /* - if(file2writeMetaData.exists()) { - if(file2writeMetaData.getAbsolutePath().contains("ultihopTests/Alice_42/1/sha")) { - Log.writeLog(this, this.toString(), "\nDEBUGGING_Multihop_Bug #1: " + - "\nfile2WriteMetaData:" + file2writeMetaData.getAbsolutePath() + - "\nexists:" + file2writeMetaData.exists() + - "\ncanWrite:" + file2writeMetaData.canWrite() - ); - } - this.metaFile.delete(); - this.metaFile.createNewFile(); - } - */ - - try { - /* - if(file2writeMetaData.getAbsolutePath().contains("ultihopTests/Alice_42/1/sha")) { - Log.writeLog(this, this.toString(), "\nDEBUGGING_Multihop_Bug #1: open:" + - "\nfile2WriteMetaData:" + file2writeMetaData.getAbsolutePath() + - "\nexists:" + file2writeMetaData.exists() + - "\ncanWrite:" + file2writeMetaData.canWrite() - ); - } - */ - FileOutputStream fos = new FileOutputStream(file2writeMetaData); - Log.writeLog(this, this.toString(), "\\nDEBUGGING_Multihop_Bug: write meta data to:" + - "\nfile2WriteMetaData:" + file2writeMetaData.getAbsolutePath() + - "\nexists:" + file2writeMetaData.exists() + - "\ncanWrite:" + file2writeMetaData.canWrite() - ); - DataOutputStream dos = new DataOutputStream(fos); - - // do it as first element - shure how many bytes we read.. - ASAPSerialization.writeASAPHopList(this.hopList, dos); - - dos.writeUTF(this.uri); - dos.writeUTF(this.getExtraAsString()); - dos.writeUTF(SerializationHelper.collection2String(this.recipients)); - dos.writeUTF(SerializationHelper.collection2String(this.deliveredTo)); - - // write offsetList - dos.writeUTF(this.messageStartOffsetListAsString()); - - fos.close(); - dos.close(); - } - catch(IOException ioe) { - // TODO: debugging code - Log.writeLog(this, this.toString(), "\nDEBUGGING_Multihop_Bug #3: file2WriteMetaData:" + - "\nfile2WriteMetaData:" + file2writeMetaData.getAbsolutePath() + - "\nexists:" + file2writeMetaData.exists() + - "\ncanWrite:" + file2writeMetaData.canWrite()); - String fname = new StringTokenizer(ioe.getLocalizedMessage()).nextToken(); - Log.writeLog(this, this.toString(), "\nDEBUGGING_Multihop_Bug #4: not found" + - "\nfile2WriteMetaData:" + file2writeMetaData.getAbsolutePath()); - File fNotFound = new File(fname); - Log.writeLog(this, this.toString(), "\nDEBUGGING_Multihop_Bug #5: file not found" + - "\nfile2WriteMetaData:" + fNotFound.getAbsolutePath() + - "\nexists:" + fNotFound.exists() + - "\ncanWrite:" + fNotFound.canWrite()); - System.out.flush(); - try { - // debugging output - Thread.sleep(10); - } catch (InterruptedException e) { - //throw new RuntimeException(e); - } - Log.writeLog(this, this.toString(), "DEBUGGING_Multihop_Bug - try write again"); - FileOutputStream fos = new FileOutputStream(fNotFound); - fos.write(42); - // never reaches that point - Log.writeLog(this, this.toString(), "DEBUGGING_Multihop_Bug - wrote"); - - throw ioe; - } - } - - private String messageStartOffsetListAsString() { - StringBuilder sb = new StringBuilder(); - - boolean first = true; - for(Long offset : this.messageStartOffsets) { - if(!first) { - sb.append(ASAPLogHelper.SERIALIZATION_DELIMITER); - } - first = false; - sb.append(offset.toString()); - } - - return sb.toString(); - } - - private String getExtraAsString() throws IOException { - StringBuilder sb = new StringBuilder(); - - boolean first = true; - for(String key : this.extraData.keySet()) { - String value = this.extraData.get(key); - if(value == null) { - throw new IOException("null value not allowed in extra data"); - }; - - if(first) { first = false; } - else { sb.append(ASAPLogHelper.SERIALIZATION_DELIMITER); } - - sb.append(key); - sb.append(ASAPLogHelper.SERIALIZATION_DELIMITER); - sb.append(value); - } - - return sb.toString(); - } - - private void setExtraByString(String extraString) throws IOException { - if(extraString == null) return; - - try { - HashMap extra = new HashMap<>(); - StringTokenizer st = new StringTokenizer(extraString, ASAPLogHelper.SERIALIZATION_DELIMITER); - while (st.hasMoreTokens()) { - String key = st.nextToken(); - String value = st.nextToken(); - - extra.put(key, value); - } - - this.extraData = extra; - } - catch(RuntimeException e) { - // missing token or something - throw new IOException(e.getLocalizedMessage()); - } - } - - private ArrayList messageOffsetString2List(String s) { - ArrayList longList = new ArrayList<>(); - - if(s == null || s.length() == 0) return longList; - - StringTokenizer t = new StringTokenizer(s, ASAPLogHelper.SERIALIZATION_DELIMITER); - - while(t.hasMoreTokens()) { - Long offsetLong = Long.parseLong(t.nextToken()); - longList.add(offsetLong); - } - - return longList; - } - - @Override - public int getNumberMessage() { - if(this.messageFile.length() == 0) return 0; - - return this.messageStartOffsets.size() + 1; - } - - @Override - public int getEra() throws IOException { - return this.era; - } - - public String toString() { - return "sender: " + this.sender + " | era: " + era + " | metafile: " + this.metaFile; - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalOnlinePeersChangedListener.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalOnlinePeersChangedListener.java deleted file mode 100644 index a9058af..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalOnlinePeersChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.sharksystem.asap.engine; - -public interface ASAPInternalOnlinePeersChangedListener { - void notifyOnlinePeersChanged(ASAPInternalPeer engine); -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeer.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeer.java deleted file mode 100644 index b68b03f..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeer.java +++ /dev/null @@ -1,164 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.ASAPConnectionHandler; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.protocol.*; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.fs.ExtraData; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Set; - -/** - * There is an ASAPEngine that stores its data with a filesystem. - * One significant parameter is a root directory. - * - * It is good practice to use a different root for each application. - * - * It is also common that more than one ASAP based app is running - * on one machine. Thus, different ASAP filesystem based engine are - * to deal with the data depending on the ASAP format. - * - * That interface hides those different engines. - */ -public interface ASAPInternalPeer extends ASAPConnectionHandler, ExtraData { - long DEFAULT_MAX_PROCESSING_TIME = Long.MAX_VALUE; - - /** - * get an existing engine - * @param format - * @return - * @throws ASAPException engine does not exist - * @throws IOException - */ - ASAPEngine getEngineByFormat(CharSequence format) throws ASAPException, IOException; - - boolean asapRoutingAllowed(CharSequence applicationFormat) throws IOException, ASAPException; - - void setAsapRoutingAllowed(CharSequence applicationFormat, boolean allowed) - throws IOException, ASAPException; - - /** - * return already existing or create an engine for a given format / application name - * @param format - * @return - * @throws ASAPException - * @throws IOException - */ - ASAPEngine createEngineByFormat(CharSequence format) throws ASAPException, IOException; - - ASAPChunkAssimilatedListener getListenerByFormat(CharSequence format) throws ASAPException; - - /** - * get or create engine for a given application - mainly means: setup folder - * @param format - * @return - */ - ASAPEngine getASAPEngine(CharSequence format) throws IOException, ASAPException; - - void pushInterests(OutputStream os) throws IOException, ASAPException; - - Set getOnlinePeers(); - - boolean existASAPConnection(CharSequence recipient); - - ASAPConnection getASAPConnection(CharSequence recipient); - - CharSequence getOwner(); - - void newEra() throws IOException, ASAPException; - - void setASAPChunkReceivedListener(CharSequence appName, ASAPChunkAssimilatedListener listener) throws ASAPException; - - void addOnlinePeersChangedListener(ASAPInternalOnlinePeersChangedListener listener); - - void removeOnlinePeersChangedListener(ASAPInternalOnlinePeersChangedListener listener); - - /** - * @return true if the asap management engine is up and running - */ - boolean isASAPManagementEngineRunning(); - - EngineSetting getEngineSettings(CharSequence format) throws ASAPException; - - /** - * @return all formats currently supported by this mulit engine - */ - Set getFormats(); - - void activateOnlineMessages(); - void deactivateOnlineMessages(); - - /** - * A transient message is not stored and not meant to be forwarded. Sending a transient message has no effect - * without a running encounter. Despite that, it is an ordinary ASAP message - described by an application/format - * and an optional uri. - * - * @param nextHopPeerIDs A peer can have multiple encounter at the same time. This list - if present, names -* potential message receiver. If null, message is sent to any open connection. An exception - * is not thrown if there is no connection to one or more peers in the list - * @param format message application / format - * @param urlTarget describe message within your app - * @param messageAsBytes serialized message - * @throws IOException - * @throws ASAPException - */ - void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, - Set nextHopPeerIDs, byte[] messageAsBytes) throws IOException, ASAPException; - - /** - * Send a transient message to a single peer. - * An exception is thrown if there is no open connection the the specified peer - * @param format - * @param urlTarget - * @param nextHopPeerID - * @param messageAsBytes - * @throws IOException - * @throws ASAPException - */ - void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, - CharSequence nextHopPeerID, byte[] messageAsBytes) throws IOException, ASAPException; - - /** - * Send a transient message to any peer we have an open connection to. - * - * @param format - * @param urlTarget - * @param messageAsBytes - * @throws IOException - * @throws ASAPException - */ - void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, byte[] messageAsBytes) - throws IOException, ASAPException; - - /** - * @deprecated use sendTransientASAPAssimilateMessage instead - * @param format - * @param urlTarget - * @param era - * @param recipients - * @param messageAsBytes - * @throws IOException - * @throws ASAPException - */ - void sendOnlineASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, int era, - Set recipients, byte[] messageAsBytes) throws IOException, ASAPException; - - void sendOnlineASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, int era, byte[] messageAsBytes) - throws IOException, ASAPException; - - void setASAPKeyStore(ASAPKeyStore ASAPKeyStore); - ASAPKeyStore getASAPKeyStore(); - - ASAPCommunicationSetting getASAPCommunicationControl(); - - ASAPKeyStore getAsapKeyStore() throws ASAPSecurityException; - - ExtraData getExtraData() throws SharkException, IOException; - - void setSecurityAdministrator(DefaultSecurityAdministrator securityAdministrator); - -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeerFS.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeerFS.java deleted file mode 100644 index e191caf..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalPeerFS.java +++ /dev/null @@ -1,757 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.crypto.*; -import net.sharksystem.fs.ExtraData; -import net.sharksystem.fs.ExtraDataFS; -import net.sharksystem.utils.*; -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.listenermanager.management.ASAPManagementMessageHandler; -import net.sharksystem.asap.protocol.*; - -import java.io.*; -import java.util.*; - -public class ASAPInternalPeerFS implements - ASAPInternalPeer, ASAPConnectionListener, ThreadFinishedListener, ASAPUndecryptableMessageHandler/*, ASAPChunkReceivedListener */ { - - private static final String DEFAULT_ASAP_MANAGEMENT_ENGINE_ROOTFOLDER = "ASAPManagement"; - private final CharSequence rootFolderName; - private final ASAPChunkAssimilatedListener listener; - private CharSequence owner; - private HashMap folderMap; - private final long maxExecutionTime; - private ASAPKeyStore asapKeyStore; - private DefaultSecurityAdministrator defaultSecurityAdministrator = new DefaultSecurityAdministrator(); - private InMemoASAPKeyStore inMemoASAPKeyStore; - - public ASAPPoint2PointCryptoSettings getASAPCommunicationCryptoSettings() { - return this.defaultSecurityAdministrator; - } - - public void setSecurityAdministrator(DefaultSecurityAdministrator securityAdministrator) { - this.defaultSecurityAdministrator = securityAdministrator; - } - - public ASAPCommunicationSetting getASAPCommunicationControl() { - return this.defaultSecurityAdministrator; - } - - public static ASAPInternalPeer createASAPPeer(CharSequence owner, CharSequence rootFolder, - long maxExecutionTime, - Collection supportFormats, - ASAPChunkAssimilatedListener listener) - throws ASAPException, IOException { - - return new ASAPInternalPeerFS(owner, rootFolder, maxExecutionTime, supportFormats, listener); - } - - public static ASAPInternalPeer createASAPPeer(CharSequence owner, CharSequence rootFolder, - Collection supportFormats, - ASAPChunkAssimilatedListener listener) - throws ASAPException, IOException { - - return new ASAPInternalPeerFS(owner, rootFolder, DEFAULT_MAX_PROCESSING_TIME, supportFormats, listener); - } - - public static ASAPInternalPeer createASAPPeer(CharSequence owner, CharSequence rootFolder, - long maxExecutionTime, - ASAPChunkAssimilatedListener listener) throws ASAPException, IOException { - return new ASAPInternalPeerFS(owner, rootFolder, maxExecutionTime, listener); - } - - public static ASAPInternalPeer createASAPPeer(CharSequence owner, CharSequence rootFolder, - ASAPChunkAssimilatedListener listener) throws ASAPException, IOException { - return new ASAPInternalPeerFS(owner, rootFolder, DEFAULT_MAX_PROCESSING_TIME, listener); - } - - public static ASAPInternalPeer createASAPPeer(CharSequence folder, ASAPChunkAssimilatedListener listener) - throws ASAPException, IOException { - - return ASAPInternalPeerFS.createASAPPeer(ASAPEngine.DEFAULT_OWNER, folder, - DEFAULT_MAX_PROCESSING_TIME, listener); - } - - /** - * assumed that a number of asap storages are already exists in subdirectories of the - * root directory. setting list can be created by iterating those storages. - * @param rootFolderName - */ - private ASAPInternalPeerFS(CharSequence owner, CharSequence rootFolderName, long maxExecutionTime, - ASAPChunkAssimilatedListener listener) throws ASAPException, IOException { - this(owner, rootFolderName, maxExecutionTime, null, listener); - } - - private ASAPInternalPeerFS(CharSequence owner, CharSequence rootFolderName, long maxExecutionTime, - Collection apps, ASAPChunkAssimilatedListener listener) - throws ASAPException, IOException { - - // owner id must not be a numerical value only - it would interfere with our era numbers - try { - Integer.parseInt(owner.toString()); - throw new ASAPException("peer id must not only be a numeric number like 42. " + - "It can be ArthurDent_42, though: " + owner); - } - catch(NumberFormatException e) { - // that's a good thing - id is not only a number - } - - this.owner = owner; - this.maxExecutionTime = maxExecutionTime; - this.rootFolderName = rootFolderName; - this.listener = listener; - - File rootFolder = new File(rootFolderName.toString()); - - if(!rootFolder.exists()) { - // create - rootFolder.mkdirs(); - } - - if (!rootFolder.isDirectory()) { - throw new ASAPException("exists but is not a directory: " + rootFolderName); - } - - this.setupFolderMap(); - - /////////////////// asap management app ////////////////////////////////////////////////////// - // check if management engine running - /* - if(!this.isASAPManagementEngineRunning()) { - Log.writeLog(this, "no asap management engine yet - set it up."); - - this.setupEngine(DEFAULT_ASAP_MANAGEMENT_ENGINE_ROOTFOLDER, ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - } - */ - - // set listener to asap management app - EngineSetting folderAndListener = folderMap.get(ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - if(folderAndListener != null) { - folderAndListener.listener = new ASAPManagementMessageHandler(this); - } - - /////////////////// not yet created engines//////////////////////////////////////////////////// - if(apps != null) { - for (CharSequence appFormat : apps) { - // check if exists - try { - this.getEngineByFormat(appFormat); - } catch (ASAPException e) { - // set it up - this.setupEngine(Utils.url2FileName(appFormat.toString()), appFormat); - } - } - } - - //this.restoreExtraData(); - -// Log.writeLog(this, "SHOULD also set up engine " + FORMAT_UNDECRYPTABLE_MESSAGES); - } - - private void setupEngine(CharSequence folderName, CharSequence formatName) throws IOException, ASAPException { - String fileName = this.rootFolderName + "/" + folderName; - Log.writeLog(this, "set up: " + formatName + " in folder " + fileName); - ASAPEngine asapEngine = ASAPEngineFS.getASAPStorage(this.getOwner().toString(), - fileName, formatName); - - asapEngine.setSecurityAdministrator(this.defaultSecurityAdministrator); - - EngineSetting setting = new EngineSetting( - fileName, // folder - this.listener// listener - ); - setting.setASAPEngine(asapEngine); - this.folderMap.put(formatName, setting); - } - - private void setupFolderMap() throws IOException, ASAPException { - this.folderMap = new HashMap<>(); - File rootFolder = new File(rootFolderName.toString()); - - Log.writeLog(this, "setting up ASAPEngine based on sub folders in " + this.rootFolderName); - File[] files = rootFolder.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - String fileName = file.getCanonicalPath(); - Log.writeLog(this, "setup engine for " + fileName); - ASAPEngine engine = ASAPEngineFS.getExistingASAPEngineFS(fileName); - EngineSetting setting = new EngineSetting( - rootFolderName + "/" + fileName, // folder - listener// listener - ); - setting.setASAPEngine(engine); - this.folderMap.put(engine.format, setting); - } - } - } - - /** - * increase era for each engine - */ - public void newEra() throws IOException, ASAPException { - for(CharSequence format : this.folderMap.keySet()) { - ASAPEngine engine = this.getEngineByFormat(format); - engine.newEra(); - } - } - - @Override - public void setASAPChunkReceivedListener(CharSequence appName, ASAPChunkAssimilatedListener listener) - throws ASAPException { - - EngineSetting engineSetting = this.folderMap.get(appName); - if(engineSetting == null) { - throw new ASAPException("there is no ASAPEngine for app/format " + appName); - } - - engineSetting.listener = listener; - } - - public CharSequence getOwner() { - return this.owner; - } - - public ASAPEngine getEngineByFormat(CharSequence format) throws ASAPException, IOException { - // get engine - EngineSetting engineSetting = this.getEngineSettings(format); - ASAPEngine asapEngine = engineSetting.engine; - - if (asapEngine == null) { - asapEngine = ASAPEngineFS.getASAPEngine(owner.toString(), engineSetting.folder.toString(), format); - engineSetting.setASAPEngine(asapEngine); // remember - keep that object - } - asapEngine.setSecurityAdministrator(this.defaultSecurityAdministrator); - return asapEngine; - } - - public boolean asapRoutingAllowed(CharSequence applicationFormat) throws IOException, ASAPException { - return this.getEngineByFormat(applicationFormat).routingAllowed(); - } - - public void setAsapRoutingAllowed(CharSequence applicationFormat, boolean allowed) - throws IOException, ASAPException { - - this.getEngineByFormat(applicationFormat).setBehaviourAllowRouting(allowed); - } - - @Override - public ASAPEngine createEngineByFormat(CharSequence format) throws ASAPException, IOException { - try { - return this.getEngineByFormat(format); - } - catch(ASAPException e) { - // does not exist yet - } - - String folderName = this.getEngineFolderByAppName(format); - ASAPEngine asapEngine = ASAPEngineFS.getASAPEngine(String.valueOf(this.getOwner()), folderName, format); - this.folderMap.put(format, new EngineSetting(folderName, listener)); - - asapEngine.setSecurityAdministrator(this.defaultSecurityAdministrator); - - return asapEngine; - } - - @Override - public ASAPChunkAssimilatedListener getListenerByFormat(CharSequence format) throws ASAPException { - EngineSetting engineSetting = this.folderMap.get(format); - if(engineSetting == null) throw new ASAPException("unknown format: " + format); - - return engineSetting.listener; - } - - private String getEngineFolderByAppName(CharSequence appName) { - return this.rootFolderName.toString() + "/" + Utils.url2FileName(appName.toString()); - } - - @Override - public ASAPEngine getASAPEngine(CharSequence format) - throws IOException, ASAPException { - - String foldername = this.getEngineFolderByAppName(format); - // already exists? - try { - ASAPEngine existingASAPEngineFS = ASAPEngineFS.getExistingASAPEngineFS(foldername); - if(existingASAPEngineFS != null) { - return existingASAPEngineFS; - } - } - catch(ASAPException e) { - Log.writeLog(this, "engine does not yet exist. folder " + foldername); - } - - Log.writeLog(this, "setup engine with folder" + foldername); - ASAPEngine asapEngine = ASAPEngineFS.getASAPEngine(this.getOwner().toString(), foldername, format); - // add to folderMap - EngineSetting setting = new EngineSetting(foldername, this.listener); - setting.setASAPEngine(asapEngine); - this.folderMap.put(format, setting); - - return asapEngine; - } - - public EngineSetting getEngineSettings(CharSequence format) throws ASAPException { - EngineSetting folderAndListener = this.folderMap.get(format); - if(folderAndListener == null) - throw new ASAPException("no folder for owner / format: " + owner + "/" + format); - - return folderAndListener; - } - - public Set getFormats() { - return this.folderMap.keySet(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // connection management // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public ASAPConnection handleConnection(InputStream is, OutputStream os) throws IOException, ASAPException { - return this.handleConnection(is, os, false, false); - } - - public ASAPConnection handleConnection(InputStream is, OutputStream os, - boolean encrypt, boolean sign) throws IOException, ASAPException { - - return this.handleConnection(is, os,false, false,null, null); - } - - public ASAPConnection handleConnection(InputStream is, OutputStream os, ASAPEncounterConnectionType connectionType) - throws IOException, ASAPException { - - return this.handleConnection(is, os,false, false, connectionType, null, null); - } - - /** - * - * @deprecated need connection type - */ - public ASAPConnection handleConnection( - InputStream is, OutputStream os, boolean encrypt, boolean sign, - Set appsWhiteList, Set appsBlackList - ) throws IOException, ASAPException { - - return this.handleConnection(is, os, encrypt, sign, - ASAPEncounterConnectionType.UNKNOWN, appsWhiteList, appsBlackList); - } - - public ASAPConnection handleConnection( - InputStream is, OutputStream os, boolean encrypt, boolean sign, ASAPEncounterConnectionType connectionType, - Set appsWhiteList, Set appsBlackList) throws IOException, ASAPException { - - if(appsWhiteList == null) appsWhiteList = new HashSet<>(); // empty set no null - if(appsBlackList == null) appsBlackList = new HashSet<>(); // empty set no null - - // TODO add white / black list. - ASAPSessionImpl asapConnection = new ASAPSessionImpl( - is, os, this, new ASAP_Modem_Impl(), - this, this.asapKeyStore, - maxExecutionTime, this, this, encrypt, sign, connectionType); - - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("handleConnection"); - Log.writeLog(this, sb.toString()); - - this.announceNewEra(); // announce when connection is actually established - - Thread thread = new Thread(asapConnection); - thread.start(); - - // remember - this.runningThreads.add(thread); - - sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("launched new asapConnection thread, total number is now: "); - sb.append(this.runningThreads.size()); - Log.writeLog(this, sb.toString()); - - return asapConnection; - } - - public void announceNewEra() throws IOException, ASAPException { - Log.writeLog(this, "announce new era"); - for(CharSequence format : this.folderMap.keySet()) { - ASAPInternalStorage asapStorage = this.getEngineByFormat(format); - asapStorage.newEra(); - } - } - - /** all running threads */ - private List runningThreads = new ArrayList<>(); - - @Override - public void finished(Thread thread) { - if(thread == null) { - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("finished thread cannot be null - do nothing"); - Log.writeLogErr(this, sb.toString()); - return; - } - - this.runningThreads.remove(thread); - - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("thread terminated - number of running threads is now: "); - sb.append(this.runningThreads.size()); - Log.writeLog(this, sb.toString()); - } - - // threads connected to a peer - private Map connectedThreads = new HashMap<>(); - private Map threadPeerNames = new HashMap<>(); - - private List onlinePeersChangedListeners = new ArrayList<>(); - public void addOnlinePeersChangedListener(ASAPInternalOnlinePeersChangedListener listener) { - this.onlinePeersChangedListeners.add(listener); - } - - public void removeOnlinePeersChangedListener(ASAPInternalOnlinePeersChangedListener listener) { - this.onlinePeersChangedListeners.remove(listener); - } - - @Override - public boolean isASAPManagementEngineRunning() { - try { - ASAPEngine engineByFormat = this.getEngineByFormat(ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - if(engineByFormat == null) { - return false; - } - } catch (ASAPException | IOException e) { - return false; - } - - return true; - } - - private void notifyOnlinePeersChangedListener() { - if(!this.connectedThreads.isEmpty()) { - Log.writeLog(this, - "#online peers: " + this.connectedThreads.keySet().size() - + " | " + SerializationHelper.collection2String(this.connectedThreads.keySet())); - } else { - Log.writeLog(this, "no (more) peers: "); - } - - if(this.onlinePeersChangedListeners != null && !this.onlinePeersChangedListeners.isEmpty()) { - for(ASAPInternalOnlinePeersChangedListener listener: this.onlinePeersChangedListeners) { - listener.notifyOnlinePeersChanged(this); - } - } else { - Log.writeLog(this, "online peer changed but no listener"); - } - } - - public Set getOnlinePeers() { - if(!this.connectedThreads.isEmpty()) { - Log.writeLog(this, - "getOnlinePeers called | #online peers: " + this.connectedThreads.keySet().size() - + " | " + SerializationHelper.collection2String(this.connectedThreads.keySet())); - } else { - Log.writeLog(this, "getOnlinePeers called | no (more) peers: "); - } - - return this.connectedThreads.keySet(); - } - - @Override - public void asapConnectionStarted(String remotePeerName, ASAPConnection asapConnection) { - if(asapConnection == null) { - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("asap connection started but asapConnection terminated cannot be null - do nothing"); - Log.writeLogErr(this,sb.toString()); - return; - } - - /* we must do it handleConnection - this method is called when we are about processing the first interest pdu - try { - this.announceNewEra(); - } catch (IOException | ASAPException e) { - Log.writeLogErr(this, "could not announce new era: " + e.getLocalizedMessage()); - } - */ - - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("asap connection started, got a peername: "); - sb.append(remotePeerName); - Log.writeLog(this, sb.toString()); - - this.connectedThreads.put(remotePeerName, asapConnection); - this.threadPeerNames.put(asapConnection, remotePeerName); - this.notifyOnlinePeersChangedListener(); - } - - @Override - public synchronized void asapConnectionTerminated(Exception terminatingException, ASAPConnection asapConnection) { - if(asapConnection == null) { - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("terminated connection cannot be null - do nothing"); - Log.writeLogErr(this, sb.toString()); - return; - } - - // get asapConnection name - CharSequence peerName = this.threadPeerNames.remove(asapConnection); - this.connectedThreads.remove(peerName); - - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("asapConnection terminated; was connected to: "); - - if(peerName != null) { - sb.append(peerName); - } else { - sb.append("null"); - } - - Log.writeLog(this, sb.toString()); - - if(peerName != null) { - try { - this.announceNewEra(); - } catch (IOException | ASAPException e) { - Log.writeLogErr(this,"error when announcing new era: " + e.getLocalizedMessage()); - } - - this.notifyOnlinePeersChangedListener(); - } else { - Log.writeLog(this, - "asap connection terminated connected to nobody: don't change era / don't notify listeners"); - } - } - - @Override - public boolean existASAPConnection(CharSequence recipient) { - return this.getASAPConnection(recipient) != null; - } - - @Override - public ASAPConnection getASAPConnection(CharSequence recipient) { - return this.connectedThreads.get(recipient); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ASAP management // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public void pushInterests(OutputStream os) throws IOException, ASAPException { - ASAP_1_0 protocol = new ASAP_Modem_Impl(); -/* - // in any case: issue an interest for management information first - Log.writeLog(this, "send interest on " + ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - protocol.interest(this.owner, null, ASAP_1_0.ASAP_MANAGEMENT_FORMAT,null, -1, -1, os, false); -*/ - if(this.folderMap.size() > 0) { - Log.writeLog(this, "start sending interest for apps/formats"); - } else { - Log.writeLog(this, "no more apps/formats on that engine - no interests to be sent"); - } - - // management messages must be sent first - if any - try { - // exists? - ASAPEngine managementEngine = this.getEngineByFormat(ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - Log.writeLog(this, "send interest for app/format: " + ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - protocol.interest(this.owner, null, - ASAP_1_0.ASAP_MANAGEMENT_FORMAT, - null, ASAP_1_0.ERA_NOT_DEFINED, ASAP_1_0.ERA_NOT_DEFINED, - os, - this.getASAPCommunicationCryptoSettings()); - } - catch(Exception e) { - // ignore - engine does not exist - } - // issue an interest for each owner / format combination - for(CharSequence format : this.folderMap.keySet()) { - if(format.toString().equalsIgnoreCase(ASAP_1_0.ASAP_MANAGEMENT_FORMAT)) continue; // already sent - ASAPEngine engine = this.getEngineByFormat(format); - - engine.sendInterest(this.owner, protocol, os); - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Online management // - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void activateOnlineMessages() { -// ASAPOnlineMessageSender asapOnlineMessageSender = new ASAPOnlineMessageSenderEngineSide(this); - - // iterate engines - for(ASAPEngine engine : this.getEngines()) { -// engine.attachASAPMessageAddListener(asapOnlineMessageSender); - engine.activateOnlineMessages(this); - } - } - - @Override - public void deactivateOnlineMessages() { - // iterate engines - for(ASAPEngine engine : this.getEngines()) { - engine.deactivateOnlineMessages(); - } - } - - - @Override - public void setASAPKeyStore(ASAPKeyStore asapKeyStore) { - this.asapKeyStore = asapKeyStore; - } - - public ASAPKeyStore getASAPKeyStore() { - return this.asapKeyStore; - } - - public void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence uri, byte[] messageAsBytes) - throws IOException, ASAPException { - this.sendTransientASAPAssimilateMessage(format, uri, (Set)null, messageAsBytes); - } - - public void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence uri, - Set nextHopPeerIDs, byte[] messageAsBytes) throws IOException, ASAPException { - - this.sendOnlineASAPAssimilateMessage(format, uri, ASAP.TRANSIENT_ERA, nextHopPeerIDs, messageAsBytes); - } - - public void sendTransientASAPAssimilateMessage(CharSequence format, CharSequence uri, - CharSequence nextHopPeerID, byte[] messageAsBytes) throws IOException, ASAPException { - - if(nextHopPeerID == null) throw new ASAPException("next hop peer id must not be null"); - - if(!this.existASAPConnection(nextHopPeerID)) { - String log = "cannot send transient message. No open connection to peer with id: " + nextHopPeerID; - Log.writeLog(this, log); - throw new ASAPException(log); - } - - Set nextHopPeerIDs = new HashSet<>(); - nextHopPeerIDs.add(nextHopPeerID); - this.sendOnlineASAPAssimilateMessage(format, uri, ASAP.TRANSIENT_ERA, nextHopPeerIDs, messageAsBytes); - } - - public void sendOnlineASAPAssimilateMessage(CharSequence format, CharSequence uri, int era, byte[] messageAsBytes) - throws IOException, ASAPException { - - this.sendOnlineASAPAssimilateMessage(format, uri, era, null, messageAsBytes); - } - - public void sendOnlineASAPAssimilateMessage(CharSequence format, CharSequence uri, int era, - Set receiver, byte[] messageAsBytes) throws IOException, ASAPException { - // setup online message sender thread - Log.writeLog(this, "setup online message sender object"); - ASAPOnlineMessageSender asapOnlineMessageSender = new ASAPOnlineMessageSenderEngineSide(this); - Log.writeLog(this, "call send asap assimilate message with online message sender"); - asapOnlineMessageSender.sendASAPAssimilateMessage(format, uri, receiver, messageAsBytes, ASAP.TRANSIENT_ERA); - } - - private Collection getEngines() { - Collection engineList = new ArrayList<>(); - - if(this.folderMap.values() != null) { - for (EngineSetting engineSetting : this.folderMap.values()) { - engineList.add(engineSetting.engine); - } - } - - return engineList; - } - - private String getLogStart() { - return this.getClass().getSimpleName() /* + "(" + this + ")" */ + "(" + this.getOwner() + "): "; - } - - //////////////////////////////// handle message this peer cannot decrypt - @Override - public void handleUndecryptableMessage( - ASAPCryptoAlgorithms.EncryptedMessagePackage encryptedMessagePackage, - CharSequence receiver) { - - Log.writeLog(this, "handle undecryptable messages from " + receiver); - - try { - ASAPEngine undecryptEngine = - this.getASAPEngine(ASAPUndecryptableMessageHandler.FORMAT_UNDECRYPTABLE_MESSAGES); - - undecryptEngine.add( - URI_UNDECRYPTABLE_MESSAGES, - ASAPCryptoAlgorithms.getEncryptedMessagePackageAsBytes(encryptedMessagePackage)); - } catch (IOException | ASAPException e) { - Log.writeLog(this, "cannot handle undecrypted messages - no engine present"); - } - } - - ///////////////////////////////// SharkNet - @Override - public ASAPKeyStore getAsapKeyStore() throws ASAPSecurityException { - if(this.inMemoASAPKeyStore == null) { - this.inMemoASAPKeyStore = new InMemoASAPKeyStore(this.getOwner().toString()); - } - return this.inMemoASAPKeyStore; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - // make extra data persist // - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - private ExtraData extraData = null; - - public ExtraData getExtraData() throws SharkException, IOException { - if(this.extraData == null) { - this.extraData = new ExtraDataFS(this.rootFolderName, "asapPeerExtraData"); - } - - return this.extraData; - } - - public void putExtra(CharSequence key, byte[] value) throws IOException, SharkException { - this.getExtraData().putExtra(key, value); - } - - @Override - public void putExtra(CharSequence key, Integer value) throws IOException, SharkException { - this.getExtraData().putExtra(key, value); - } - - @Override - public void putExtra(CharSequence key, CharSequence value) throws IOException, SharkException { - this.getExtraData().putExtra(key, value); - } - - @Override - public void putExtra(CharSequence key, Set value) throws IOException, SharkException { - this.getExtraData().putExtra(key, value); - } - - public byte[] getExtra(CharSequence key) throws IOException, SharkException { - return this.getExtraData().getExtra(key); - } - - @Override - public int getExtraInteger(CharSequence key) throws IOException, SharkException { - return this.getExtraData().getExtraInteger(key); - } - - @Override - public Set getExtraCharSequenceSetParameter(CharSequence key) throws IOException, SharkException { - return this.getExtraData().getExtraCharSequenceSetParameter(key); - } - - @Override - public String getExtraString(CharSequence key) throws IOException, SharkException { - return this.getExtraData().getExtraString(key); - } - - @Override - public void removeAll() throws IOException, SharkException { - this.getExtraData().removeAll(); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPInternalStorage.java b/src/main/java/net/sharksystem/asap/engine/ASAPInternalStorage.java deleted file mode 100644 index 307a68d..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPInternalStorage.java +++ /dev/null @@ -1,172 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.*; -import net.sharksystem.asap.listenermanager.management.ASAPManagementStorage; - -import java.io.IOException; -import java.util.Collection; -import java.util.Set; - -/** - * - * Break down of a communication channel in ad-hoc networks is normal and barely failure. - * That chunk storage is meant to keep messages which are produced by an - * app for later transmission. - * - * Messages which cannot be sent to their recipients can be stored in ASAP chunks. - * Each chunk is addressed with an URI (comparable to URIs e.g. in Android - * Content Provider) - * - * Applications can easily store their messages by calling add(URI, message). - * That message is stored in a chunk addressed by the URI. - * - * Each chunk has a recipient list which can be changed anytime. The ASAPEngine - * uses those information for sending such stored messages whenever a peer - * establishes a connection. - * - * It is recommended to use ASAPEngineFS to set up that framework. - * Create a ASAPEngine like this - * - *
- * AASPReader reader = ...;
- * ASAPStorage myStorage = ASAPEngineFS.getASAPEngine("EngineName", "ChunkStorageRootFolder", reader);
- * 
- * - * An ASAPReader must be implemented prior using that framework. Objects of - * that class are called whenever another peer transmits messages to the - * local peer. @see AASPReader - * - * Chunks are structured by eras. In most cases, application developers don't - * have to care about era management at all. If so, take care. Eras are usually - * changed by the ASAPEngine whenever a peer (re-) connects. In that case, the - * current era is declared to be finished and an new era is opened. - * Any new message is now tagged as message from that new era. The ASAPEngine - * transmits all message to the peer which are stored after the final - * encounter. If no encounter ever happened - all available messages are - * transmitted. - * - * @see ASAPEngine - * - * @author thsc - */ -public interface ASAPInternalStorage extends ASAPStorage { - /** - * Creates a channel with named recipients - we call it a closed channel in opposite - * to an open channel. - * - * Peers must not forward messages from a closed to other peers than those in recipient list. - * - * @param uri - * @param recipients - * @throws IOException - */ - void createChannel(CharSequence uri, Collection recipients) throws IOException, ASAPException; - - /** - * Create channel (owner can differ from local peer owing this asap engine) - * @param owner - * @param uri - * @param recipients - * @throws IOException - * @throws ASAPException - */ - void createChannel(CharSequence owner, CharSequence uri, Collection recipients) throws IOException, ASAPException; - - /** - * Create a channel with only two members - creator and recipient - * @param urlTarget - * @param recipient - * @throws IOException - */ - void createChannel(CharSequence urlTarget, CharSequence recipient) throws IOException, ASAPException; - - /** - * Create open channel - * @param urlTarget - * @throws IOException - * @throws ASAPException - */ - void createChannel(CharSequence urlTarget) throws IOException, ASAPException; - - /** - * Chunks are delivered when seeing other peers. This flag allows to decide whether delivered chunks - * are to be deleted. - * @param drop - */ -// void setDropDeliveredChunks(boolean drop) throws IOException; - - /** - * Chunks are delivered when seeing other peers. Default behaviour is to send only message which - * are in local peers own storage. A peer can also have received messages in an incoming storage. - * This flag allows to force even delivery of received messages from incoming storages. Basis of - * multihop communication. - * - * @param drop - */ -// void setSendReceivedChunks(boolean drop) throws IOException; - - /** - /** - * returns recipient list - * - * @param urlTarget chunk address - * @throws IOException - * @return - */ - Set getRecipients(CharSequence urlTarget) throws IOException; - - void addRecipient(CharSequence urlTarget, CharSequence recipient) throws IOException; - void removeRecipient(CharSequence urlTarget, CharSequence recipient) throws IOException; - - /** - * Add a message to that chunk. - * @param uri message topic - * @param message Message to be kept for later transmission - * @throws IOException - */ - void add(CharSequence uri, CharSequence message) throws IOException; - - void attachASAPMessageAddListener(ASAPOnlineMessageSender asapOnlineMessageSender); - - void detachASAPMessageAddListener(); - - void setASAPManagementStorage(ASAPManagementStorage asapManagementStorage); - - boolean isASAPManagementStorageSet(); - - /** - * Create a new era - */ - public void newEra(); - - /** - * Default behaviour of ASAPEngine: Each peer / communication partner - * gets its own chunk storage. That storage is filled during asap - * synchronization. That storage can be retrieved with this command. - * - * @param sender - * @return - */ - ASAPChunkStorage getReceivedChunksStorage(CharSequence sender); - - ASAPMessages getChunkChain(int uriPosition) throws IOException, ASAPException; - - ASAPMessages getChunkChain(int uriPosition, int toEra) throws IOException, ASAPException; - - ASAPMessages getChunkChain(CharSequence uri, int toEra) throws IOException; - - ASAPMessages getChunkChain(CharSequence uri) throws IOException; - - /** - * Refresh with external system - re-read files, or whatever. - * @return refreshed object - */ - ASAPInternalStorage refresh() throws IOException, ASAPException; - - /** - * Get (and probably create a chunk - set era to this new era - * @param uri - * @param newEra - */ - ASAPInternalChunk createNewChunk(String uri, int newEra) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPMemento.java b/src/main/java/net/sharksystem/asap/engine/ASAPMemento.java deleted file mode 100644 index 4cac349..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPMemento.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.IOException; - -/** - * The memento for the engine. - * - * @author thsc - */ -interface ASAPMemento { - public void save(ASAPEngine engine) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPMementoFS.java b/src/main/java/net/sharksystem/asap/engine/ASAPMementoFS.java deleted file mode 100644 index 27208c1..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPMementoFS.java +++ /dev/null @@ -1,209 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.utils.Log; - -import java.io.*; -import java.util.HashMap; - -/** - * Engine memento implementation in filesystem. - * - * @author local - */ -class ASAPMementoFS implements ASAPMemento { - private final File rootDirectory; - private String owner; - private String format; - private int era; - private int oldestEra; - private boolean contentChanged; - private boolean dropDeliveredChunks; - private boolean sendReceivedChunks; - private HashMap lastSeen; - public long lastMementoWritten; - - public ASAPMementoFS(File rootDirectory) { - this.rootDirectory = rootDirectory; - } - - @Override - public void save(ASAPEngine engine) throws IOException { - /* - Log.writeLog(this, "\n" + - ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>save memento<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" + - ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>save memento<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - */ - String fName = this.getMementoFileName(); - - File file = new File(fName); - if(!file.exists()) { - if(!file.createNewFile()) { - throw new IOException("could not create file (problems with directory?): " + fName); - } - } - - DataOutputStream dos = new DataOutputStream(new FileOutputStream(fName)); - - long now = System.currentTimeMillis(); - - engine.lastMementoWritten = now; - this.lastMementoWritten = engine.lastMementoWritten; - dos.writeLong(now); - dos.writeUTF(engine.owner); - dos.writeUTF(engine.format); - dos.writeInt(engine.era); - dos.writeInt(engine.oldestEra); - dos.writeBoolean(engine.contentChanged); - this.contentChanged = engine.contentChanged; - dos.writeBoolean(engine.dropDeliveredChunks); - dos.writeBoolean(engine.routingAllowed); - - // write lastSeen hash map - if(engine.lastSeen != null && !engine.lastSeen.isEmpty()) { - for(String key : engine.lastSeen.keySet()) { - Integer era = engine.lastSeen.get(key); - - // write peer and era - dos.writeUTF(key); - dos.writeInt(era); - } - } - - //Log.writeLog(this, "saved: " + this); - } - - private void setDefaults(ASAPEngine engine) { - // set defaults - engine.owner = ASAPEngine.DEFAULT_OWNER; - engine.format = ASAP_1_0.ANY_FORMAT.toString(); - engine.era = ASAPEngine.DEFAULT_INIT_ERA; - engine.oldestEra = ASAPEngine.DEFAULT_INIT_ERA; - engine.lastSeen = new HashMap<>(); - engine.dropDeliveredChunks = false; - engine.routingAllowed = true; - } - - public void read() throws IOException { - String fName = this.getMementoFileName(); - - File file = new File(fName); - if(!file.exists()) { - return; - } - - DataInputStream dis = new DataInputStream( - new FileInputStream(file)); - - try { - this.lastMementoWritten = dis.readLong(); - this.owner = dis.readUTF(); - this.format = dis.readUTF(); - this.era = dis.readInt(); - this.oldestEra = dis.readInt(); - this.contentChanged = dis.readBoolean(); - this.dropDeliveredChunks = dis.readBoolean(); - this.sendReceivedChunks = dis.readBoolean(); - } - catch(EOFException e) { - // ignore and work with set defaults - return; // reached end of file - nothing to do here - } - - // try to read lastSeen list - boolean first = true; - try { - for(;;) { // escapes from that loop via ioexception - String peer = dis.readUTF(); - // got one - if(first) { - // init empty list - this.lastSeen = new HashMap<>(); - first = false; - } - - Integer era = dis.readInt(); - - // remember - this.lastSeen.put(peer, era); - } - } - catch(IOException ioe) { - // ok no more data - } - dis.close(); - } - - public void restore(ASAPEngine engine) throws IOException { - String fName = this.getMementoFileName(); - - File file = new File(fName); - if(!file.exists()) { - this.setDefaults(engine); - return; - } - - DataInputStream dis = new DataInputStream( - new FileInputStream(file)); - - try { - engine.lastMementoWritten = dis.readLong(); - this.lastMementoWritten = engine.lastMementoWritten; - engine.owner = dis.readUTF(); - engine.format = dis.readUTF(); - engine.era = dis.readInt(); - engine.oldestEra = dis.readInt(); - engine.contentChanged = dis.readBoolean(); - this.contentChanged = engine.contentChanged; - engine.dropDeliveredChunks = dis.readBoolean(); - engine.routingAllowed = dis.readBoolean(); - } - catch(EOFException e) { - // ignore and work with set defaults - return; // reached end of file - nothing to do here - } - - // try to read lastSeen list - boolean first = true; - try { - for(;;) { // escapes from that loop via ioexception - String peer = dis.readUTF(); - // got one - if(first) { - // init empty list - engine.lastSeen = new HashMap<>(); - first = false; - } - - Integer era = dis.readInt(); - - // remember - engine.lastSeen.put(peer, era); - } - } - catch(IOException ioe) { - // ok no more data - } - dis.close(); - - //Log.writeLog(this, "restored: " + this); - } - - private String getMementoFileName() { - return this.rootDirectory + "/" + ASAPEngineFS.MEMENTO_FILENAME; - } - - public String getFormat() { - return this.format; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("changed == "); - sb.append(this.contentChanged); - sb.append(" | written == "); - sb.append(this.lastMementoWritten); - - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPMessagesMerger.java b/src/main/java/net/sharksystem/asap/engine/ASAPMessagesMerger.java deleted file mode 100644 index f37e0c3..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPMessagesMerger.java +++ /dev/null @@ -1,399 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPChunk; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPMessageCompare; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.utils.PeerIDHelper; - -import javax.xml.transform.Source; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -public class ASAPMessagesMerger implements ASAPMessages { - private final ASAPMessageCompare messageCompare; - private CharSequence format; - private CharSequence uri; - private int size; - - private final ASAPMessages[] messageSources; - private List newFirstPositionList = new ArrayList<>(); - private List oldFirstPositionList = new ArrayList<>(); - - private class SourceIndex { - public int wantedPosition; // overall position - public int sourceIndex; // which had fitting message - public int positionInSource; // position in source where to find message. - - public SourceIndex(int wantedPosition, int sourceIndex, int positionInSource) { - this.wantedPosition = wantedPosition; - this.sourceIndex = sourceIndex; - this.positionInSource = positionInSource; - } - } - - ASAPMessagesMerger(List messageSources, ASAPMessageCompare messageCompare) - throws ASAPException, IOException { - if(messageSources == null || messageSources.isEmpty()) - throw new ASAPException("message source must not be null or empty"); - - this.messageCompare = messageCompare; - this.size = 0; // init; - - // check integrity and find empty sources - this.format = null; - this.uri = null; - int notEmpty = 0; - for(ASAPMessages source : messageSources) { - CharSequence currentFormat = source.getFormat(); - if(this.format != null && !PeerIDHelper.sameFormat(currentFormat, this.format)) { - throw new ASAPException("message source must not have different formats: " + this.format - + " != " + currentFormat); - } - // else - this.format = currentFormat; - - CharSequence currentUri = source.getURI(); - if(this.uri != null && !PeerIDHelper.sameFormat(currentUri, this.uri)) { - throw new ASAPException("message source must not have different uris: " + this.uri - + " != " + currentUri); - } - - // else - this.uri = currentUri; - this.size += source.size(); - - if(source.size() > 0) notEmpty++; - } - - // remember no empty sources - this.messageSources = new ASAPMessages[notEmpty]; - int i = 0; - for(ASAPMessages source : messageSources) { - if(source.size() > 0) this.messageSources[i++] = source; - } - - if(this.messageCompare == null) { - // source will be returned in their order - int globalIndex = 0; - for(int sIndex = 0; sIndex < this.messageSources.length; sIndex++) { - SourceIndex index = new SourceIndex(globalIndex, sIndex, 0); - this.oldFirstPositionList.add(index); - this.newFirstPositionList.add(index); - globalIndex += this.messageSources[sIndex].size(); - } - // last entry - int lastSourceI = this.messageSources.length-1; - SourceIndex lastSourceIndex = new SourceIndex( - globalIndex-1, // last index - lastSourceI, // last source - this.messageSources[lastSourceI].size()-1); - this.oldFirstPositionList.add(lastSourceIndex); - this.newFirstPositionList.add(lastSourceIndex); - } - } - - @Override - public int size() throws IOException { - return this.size; - } - - @Override - public CharSequence getURI() { - return this.uri; - } - - @Override - public CharSequence getFormat() { - return this.format; - } - - @Override - public Iterator getMessagesAsCharSequence() throws IOException { - return new MessageMergerCharSequenceIterator(new MessageMergerIterator(true)); - } - - private class MessageMergerCharSequenceIterator implements Iterator { - private final MessageMergerIterator iter; - - MessageMergerCharSequenceIterator(MessageMergerIterator iter) { - this.iter = iter; - } - - @Override - public boolean hasNext() { - return this.iter.hasNext(); - } - - @Override - public CharSequence next() { - return new String(this.iter.next()); - } - } - - @Override - public Iterator getMessages() throws IOException { - return new MessageMergerIterator(true); - } - - private class MessageMergerIterator implements Iterator { - private final boolean chronologically; - private int currentPosition; - private byte[] lookAheadMessage = null; - - MessageMergerIterator(boolean chronologically) { - this.chronologically = chronologically; - - } - - @Override - public boolean hasNext() { - if(lookAheadMessage == null) { - // try - try { - this.lookAheadMessage = ASAPMessagesMerger.this.getMessage(currentPosition++, chronologically); - } catch (ASAPException | IOException e) { - return false; - } - } - return (this.lookAheadMessage != null); - } - - @Override - public byte[] next() { - if (this.lookAheadMessage != null) { - if (this.hasNext()) { - byte[] temp = this.lookAheadMessage; - this.lookAheadMessage = null; - return temp; - } - } - - throw new NoSuchElementException("no more messages"); - } - } - - @Override - public CharSequence getMessageAsCharSequence(int position, boolean chronologically) throws ASAPException, IOException { - return new String(this.getMessage(position, chronologically)); - } - - /** - The list is organized like this: Each entry describes a position of the merged sources: wantedPosition. - It also describes source (actually the index of the source: sourceIndex) and position of the message - in the source (positionInSource). There is not necessarily and entry for each wantedPosition - to keep - that list short. - - A entry is made if the list was empty. There will always be an entry for wantedPosition == 0. Another entry - will only added if source has changed. Assumed we would have two sources (A and B), first messages come from - A, follow by B again and so forth, list would look like this: (wantedPosition: 0, A, 0) Both positions will be - 0 in the first entry. Next entry could be: (4, B, 0). Message for position comes from source B index 0. But - where come message at 1, 2 and 3? From A. There was no change of source, no entry was made. We avoid a series of - entries like: (1, A, 1), (2, A, 2), (3, A, 3). They can easily be calculated. - */ - private SourceIndex getSourceIndex(int position, List indexList) { - if(indexList.isEmpty()) return null; // not yet initialized? - SourceIndex previousIndexEntry = null; - int i = 0; - do { - if(indexList.size() <= i) return null; - SourceIndex indexEntry = indexList.get(i++); - - if(indexEntry.wantedPosition == position) return indexEntry; // found match - - if(previousIndexEntry != null - && previousIndexEntry.wantedPosition < position - && position < indexEntry.wantedPosition) { - // we are within a range. - int offsetIndex = previousIndexEntry.wantedPosition; - int steps = position - offsetIndex; - return new SourceIndex(position, - previousIndexEntry.sourceIndex, - previousIndexEntry.positionInSource + steps); - } - - previousIndexEntry = indexEntry; - } while(previousIndexEntry.wantedPosition < position); // we have still a chance to find anything - - return null; // there is no entry - } - - private static final int FALSE = 0; - private static final int TRUE = 1; - private byte[][][] lookAheadMessages = new byte[2][][]; // actual look ahead message - private SourceIndex[][] lookAheadSourceIndex = new SourceIndex[2][]; // describes position etc. of previous - - private byte[][] getLookAheadMessages(boolean chronologically) { - byte[][] a = chronologically ? this.lookAheadMessages[TRUE] : this.lookAheadMessages[FALSE]; - - if(a == null) { // not yet initialized - a = new byte[this.messageSources.length][]; - if(chronologically) this.lookAheadMessages[TRUE] = a; - else this.lookAheadMessages[FALSE] = a; - } - - return a; - } - - private SourceIndex[] getLookAheadSourceIndex(boolean chronologically) { - SourceIndex[] s = chronologically ? this.lookAheadSourceIndex[TRUE] : this.lookAheadSourceIndex[FALSE]; - - if(s == null) { // not yet initialized - s = new SourceIndex[this.messageSources.length]; - if(chronologically) this.lookAheadSourceIndex[TRUE] = s; - else this.lookAheadSourceIndex[FALSE] = s; - } - - return s; - } - - private boolean lookAheadSettedUp = false; - private SourceIndex lookAhead(int position, List indexList, boolean chronologically) - throws ASAPException, IOException { - - int wantedLookAheadPosition = 0; - - if(!indexList.isEmpty()) { // we already made a look ahead - // get last entry - SourceIndex sourceIndex = indexList.get(indexList.size() - 1); - - // check for your own stupidity - last position is before our wanted position - we would not be here otherwise - if (sourceIndex != null && sourceIndex.wantedPosition >= position) - throw new ASAPException("internal error - look ahead algorithm buggy"); - - wantedLookAheadPosition = sourceIndex.wantedPosition + 1; - } - - byte[][] lookAheadMessages = this.getLookAheadMessages(chronologically); - SourceIndex[] lookAheadSourceIndexArray = this.getLookAheadSourceIndex(chronologically); - - if(!this.lookAheadSettedUp) { // setup - // set it up - read first message from each non empty source - this.lookAheadSettedUp = true; - for (int i = 0; i < this.messageSources.length; i++) { - lookAheadMessages[i] = this.messageSources[i].getMessage(0, chronologically); - lookAheadSourceIndexArray[i] = new SourceIndex(-1, i, 0); - } - } - - // find message for next position. - SourceIndex previousSourceIndex = null; - SourceIndex foundSourceIndex = null; - - boolean lastSourceIndexAdded; - do { - int bestSourceIndex = -1; // init source index 0 wins? - lastSourceIndexAdded = false; // not yet at least - - for (int i = 0; i < this.messageSources.length; i++) { - if(lookAheadMessages[i] == null) continue; // nothing to do in this round - if(bestSourceIndex == -1) { - // guess we have a winner without opponent - bestSourceIndex = i; - continue; - } - - boolean previousEarlier = - this.messageCompare.earlier(lookAheadMessages[bestSourceIndex], lookAheadMessages[i]); - - /* - previous earlier | chronologically | what wins? - ----------------------------------------------- - true true no change - false true i is better - true false i is better - false false no change - */ - - if (previousEarlier != chronologically) { bestSourceIndex = i; } - } - - if(bestSourceIndex == -1) // failure in algorithm - should not happen due to test of size().. - throw new ASAPException("no more message - cannot look ahead"); - - // we have a winner - foundSourceIndex = lookAheadSourceIndexArray[bestSourceIndex]; - - // now we can tell at what overall position this message is - foundSourceIndex.wantedPosition = wantedLookAheadPosition; - - if(previousSourceIndex != null) { - if(previousSourceIndex.sourceIndex != foundSourceIndex.sourceIndex) { - // remember previous - we have a change in sources - indexList.add(foundSourceIndex); - lastSourceIndexAdded = true; - } - } else { - indexList.add(foundSourceIndex); - lastSourceIndexAdded = true; - } - - // prepare next round - previousSourceIndex = foundSourceIndex; - - // read ahead - if possible - lookAheadSourceIndexArray[bestSourceIndex] = null; - lookAheadMessages[bestSourceIndex] = null; - int nextPositionInSource = foundSourceIndex.positionInSource + 1; - try { - lookAheadMessages[bestSourceIndex] = - messageSources[bestSourceIndex].getMessage(nextPositionInSource, chronologically); - - // remember read ahead - lookAheadSourceIndexArray[bestSourceIndex] = - new SourceIndex(-1, // we cannot tell yet - bestSourceIndex, nextPositionInSource); // we know where it comes from - } - catch(Exception e) { - // no more messages - } - } while(position > wantedLookAheadPosition++); - - // remember this in any case - if(!lastSourceIndexAdded) indexList.add(foundSourceIndex); - - return foundSourceIndex; - } - - private List getIndexList(boolean chronologically) { - return chronologically ? oldFirstPositionList : newFirstPositionList; - } - - private SourceIndex getSourceIndex(int position, boolean chronologically) throws ASAPException, IOException { - if(position >= this.size) - throw new ASAPException("position index must not exceed total number of messages: " - + position + " >= " + this.size); - - SourceIndex sourceIndex; - List usedList = this.getIndexList(chronologically); - - sourceIndex = this.getSourceIndex(position, usedList); - - if(sourceIndex == null) { - // cache miss - sourceIndex = this.lookAhead(position, usedList, chronologically); - } - if(sourceIndex == null) { - // still nothing - throw new ASAPException("no message at position: " + position); - } - - return sourceIndex; - } - - @Override - public byte[] getMessage(int position, boolean chronologically) throws ASAPException, IOException { - SourceIndex sourceIndex = this.getSourceIndex(position, chronologically); - return this.messageSources[sourceIndex.sourceIndex].getMessage( - sourceIndex.positionInSource, chronologically); - } - - @Override - public ASAPChunk getChunk(int position, boolean chronologically) throws IOException, ASAPException { - SourceIndex sourceIndex = this.getSourceIndex(position, chronologically); - return this.messageSources[sourceIndex.sourceIndex].getChunk(sourceIndex.positionInSource, chronologically); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSender.java b/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSender.java deleted file mode 100644 index 7b21127..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSender.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; - -import java.io.IOException; -import java.util.Set; - -public interface ASAPOnlineMessageSender { - void sendASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, Set recipients, - byte[] messageAsBytes, int era) throws IOException, ASAPException; - - void sendASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, CharSequence recipient, - byte[] messageAsBytes, int era) throws IOException, ASAPException; - - void sendASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, byte[] messageAsBytes, int era) - throws IOException, ASAPException; - - void sendASAPAssimilateMessage(CharSequence format, CharSequence urlTarget, byte[] messageAsBytes) - throws IOException, ASAPException; -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSenderEngineSide.java b/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSenderEngineSide.java deleted file mode 100644 index b7d3546..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPOnlineMessageSenderEngineSide.java +++ /dev/null @@ -1,142 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.protocol.ASAPConnection; -import net.sharksystem.asap.protocol.ASAPOnlineMessageSource; -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.asap.protocol.ASAP_Modem_Impl; -import net.sharksystem.utils.Log; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.*; - -public class ASAPOnlineMessageSenderEngineSide extends ASAPAbstractOnlineMessageSender - implements ASAPOnlineMessageSource, ASAPOnlineMessageSender { - - private final ASAPInternalPeer multiEngine; - private final ASAP_1_0 protocol = new ASAP_Modem_Impl(); - - // connections and their remote peer (recipients) - private Map connectionPeers = new HashMap<>(); - - // message for recipients - private Map> messages = new HashMap<>(); - - public ASAPOnlineMessageSenderEngineSide(ASAPInternalPeer multiEngine) { - this.multiEngine = multiEngine; - } - - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, byte[] messageAsBytes) - throws IOException, ASAPException { - this.sendASAPAssimilateMessage(format, uri, messageAsBytes, ASAPEngineFS.DEFAULT_INIT_ERA); - } - - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, byte[] messageAsBytes, int era) - throws IOException, ASAPException { - - Set onlinePeers = this.multiEngine.getOnlinePeers(); - if(onlinePeers == null || onlinePeers.size() < 1) { - Log.writeLog(this, "no online peers"); - throw new ASAPException("no online peers"); - } - - Set onlinePeerList = new HashSet<>(); - for(CharSequence peerName : onlinePeers) { - onlinePeerList.add(peerName); - Log.writeLog(this, peerName + " is online"); - } - - this.sendASAPAssimilateMessage(format, uri, onlinePeerList, messageAsBytes, era); - } - - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, Set receiver, - byte[] messageAsBytes, int era) throws IOException, ASAPException { - - if(receiver == null || receiver.size() < 1) { - // replace empty recipient list with list of online peers. - this.sendASAPAssimilateMessage(format, uri, messageAsBytes, era); - return; - } - - StringBuilder sb = Log.startLog(this); - sb.append("sendASAPAssimilate(format: "); - sb.append(format); - sb.append("| uri: "); - sb.append(uri); - sb.append("| era: "); - if(era != ASAP.TRANSIENT_ERA) sb.append(era); - else sb.append("transient"); - sb.append("| #receiver: "); - if(receiver != null) sb.append(receiver.size()); - else sb.append("null"); - sb.append("| length: "); - sb.append(messageAsBytes.length); - sb.append(")"); - Log.writeLog(this, sb.toString()); - - // each message can have multiple receiver. Iterate - - // is there an open connection to each of the receiver. - boolean foundAll = true; // optimism captain :) - for(CharSequence recipient : receiver) { - sb = Log.startLog(this); - sb.append("try to find connection for recipient: "); - sb.append(recipient); - Log.writeLog(this, sb.toString()); - if(multiEngine.existASAPConnection(recipient)) { - ASAPConnection asapConnection = multiEngine.getASAPConnection(recipient); - sb = Log.startLog(this); - sb.append("got asap connection, subscribe and store message"); - Log.writeLog(this, sb.toString()); - - // serialize message for this recipient - ByteArrayOutputStream asapPDUBytes = new ByteArrayOutputStream(); - this.protocol.assimilate(this.multiEngine.getOwner(), recipient, format, uri, era, null, // no offsets - null, messageAsBytes, asapPDUBytes, asapConnection.isSigned()); - - // I guess maps are synchronized - List messageList = this.messages.get(recipient); - if(messageList == null) { - messageList = new ArrayList<>(); - this.messages.put(recipient, messageList); - } - - messageList.add(asapPDUBytes.toByteArray()); - - // subscribe and remember it - asapConnection.addOnlineMessageSource(this); - this.connectionPeers.put(asapConnection, recipient); - } else { - sb = Log.startLog(this); - sb.append("no connection found"); - Log.writeLog(this, sb.toString()); - foundAll = false; // at least to one recipient is not open line - } - } - } - - private String getLogStart() { - return this.getClass().getSimpleName() + ": "; - } - - @Override - public void sendStoredMessages(ASAPConnection asapConnection, OutputStream os) throws IOException { - CharSequence recipient = this.connectionPeers.get(asapConnection); - - List messageList = this.messages.get(recipient); - Log.writeLog(this, this.getLogStart() + "send message(s) to " + recipient + " via: " - + os.getClass().getSimpleName()); - while(!messageList.isEmpty()) { - byte[] messageBytes = messageList.remove(0); - os.write(messageBytes); - Log.writeLog(this, "wrote pure bytes: " + messageBytes.length); - } - - this.messages.remove(recipient); - asapConnection.removeOnlineMessageSource(this); - this.connectionPeers.remove(asapConnection); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPProtocolEngine.java b/src/main/java/net/sharksystem/asap/engine/ASAPProtocolEngine.java deleted file mode 100644 index a1a0569..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPProtocolEngine.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.asap.protocol.ASAP_AssimilationPDU_1_0; -import net.sharksystem.asap.protocol.ASAP_Interest_PDU_1_0; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * @author thsc - */ -public interface ASAPProtocolEngine { - void handleASAPInterest(ASAP_Interest_PDU_1_0 asapInterest, ASAP_1_0 protocol, - String encounteredPeer, OutputStream os, ASAPEncounterConnectionType connectionType) - throws ASAPException, IOException; - - void handleASAPAssimilate(ASAP_AssimilationPDU_1_0 asapAssimilationPDU, ASAP_1_0 protocolModem, - String encounteredPeer, InputStream is, OutputStream os, - ASAPEncounterConnectionType connectionType, - ASAPChunkAssimilatedListener listener) - throws ASAPException, IOException; - - /** - * Chunks are (tried to be) delivered to their recipients during each encounter - * with another peer. After successful delivery, recipient is withdrawn from recipient - * list to prevent multiple delivery. - * - * If this flag is set, chunk are removed permanently if their are delivered - * to all their recipients. There are kept in local storage otherwise. - * @param drop - */ - void setBehaviourDropDeliveredChunks(boolean drop) throws IOException; - - /** - * engine can deliver local message but also received messages - default false - send no received messages - * @param on - */ - void setBehaviourAllowRouting(boolean on) throws IOException; - - boolean routingAllowed(); -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPSingleProcessOnlineMessageSender.java b/src/main/java/net/sharksystem/asap/engine/ASAPSingleProcessOnlineMessageSender.java deleted file mode 100644 index 4e9c8f0..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPSingleProcessOnlineMessageSender.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.protocol.ASAPConnection; -import net.sharksystem.asap.protocol.ASAPOnlineMessageSource; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Set; - -public class ASAPSingleProcessOnlineMessageSender - extends ASAPAbstractOnlineMessageSender implements ASAPOnlineMessageSource { - - private final ASAPOnlineMessageSenderEngineSide asapOnlineMessageSenderEngineSide; - - public ASAPSingleProcessOnlineMessageSender(ASAPInternalPeer multiEngine, ASAPInternalStorage source) { - this.attachToSource(source); - this.asapOnlineMessageSenderEngineSide = new ASAPOnlineMessageSenderEngineSide(multiEngine); - } - - @Override - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, Set recipients, - byte[] messageAsBytes, int era) throws IOException, ASAPException { - - this.asapOnlineMessageSenderEngineSide.sendASAPAssimilateMessage( - format, uri, recipients, messageAsBytes, era); - } - - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, byte[] messageAsBytes) - throws IOException, ASAPException { - this.sendASAPAssimilateMessage(format, uri, messageAsBytes, ASAPEngineFS.DEFAULT_INIT_ERA); - } - - @Override - public void sendASAPAssimilateMessage(CharSequence format, CharSequence uri, byte[] messageAsBytes, int era) - throws IOException, ASAPException { - - this.asapOnlineMessageSenderEngineSide.sendASAPAssimilateMessage(format, uri, messageAsBytes, era); - } - - @Override - public void sendStoredMessages(ASAPConnection asapConnection, OutputStream os) throws IOException { - this.asapOnlineMessageSenderEngineSide.sendStoredMessages(asapConnection, os); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPStorageImpl.java b/src/main/java/net/sharksystem/asap/engine/ASAPStorageImpl.java deleted file mode 100644 index fcd7fd4..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPStorageImpl.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.protocol.ASAP_1_0; - -import java.io.IOException; - -public abstract class ASAPStorageImpl implements ASAPInternalStorage { -} diff --git a/src/main/java/net/sharksystem/asap/engine/ASAPUndecryptableMessageHandler.java b/src/main/java/net/sharksystem/asap/engine/ASAPUndecryptableMessageHandler.java deleted file mode 100644 index c85fb1f..0000000 --- a/src/main/java/net/sharksystem/asap/engine/ASAPUndecryptableMessageHandler.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.crypto.ASAPCryptoAlgorithms; - -public interface ASAPUndecryptableMessageHandler { - String FORMAT_UNDECRYPTABLE_MESSAGES = "asap/undecryptable"; - String URI_UNDECRYPTABLE_MESSAGES = "asap://undecryptable"; - /** - * Peer can (and should) receive encrypted messages without being receiver. A peer is not able - * to encrypt that message but could store and forward. That is what ASAP is about. - */ - void handleUndecryptableMessage(ASAPCryptoAlgorithms.EncryptedMessagePackage encryptedMessage, CharSequence receiver); -} diff --git a/src/main/java/net/sharksystem/asap/engine/CryptoControl.java b/src/main/java/net/sharksystem/asap/engine/CryptoControl.java deleted file mode 100644 index 2b9021b..0000000 --- a/src/main/java/net/sharksystem/asap/engine/CryptoControl.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.protocol.ASAP_PDU_1_0; - -public interface CryptoControl { - boolean allowed2Process(ASAP_PDU_1_0 pdu); -} diff --git a/src/main/java/net/sharksystem/asap/engine/DefaultSecurityAdministrator.java b/src/main/java/net/sharksystem/asap/engine/DefaultSecurityAdministrator.java deleted file mode 100644 index 3c024d1..0000000 --- a/src/main/java/net/sharksystem/asap/engine/DefaultSecurityAdministrator.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.protocol.ASAP_AssimilationPDU_1_0; -import net.sharksystem.asap.protocol.ASAP_PDU_1_0; -import net.sharksystem.asap.crypto.ASAPPoint2PointCryptoSettings; -import net.sharksystem.utils.Log; - -import java.io.IOException; - -public class DefaultSecurityAdministrator implements ASAPCommunicationSetting, - ASAPEnginePermissionSettings, CryptoControl, ASAPPoint2PointCryptoSettings { - - private boolean receivedMessageMustBeEncrypted = false; - private boolean receivedMessagesMustBeSigned = false; - private boolean sendEncrypted = false; - private boolean sendSigned; - - @Override - public void setRememberEncounteredPeers(boolean on) throws IOException { - - } - - @Override - public void setReceivedMessagesMustBeEncrypted(boolean on) throws IOException { - this.receivedMessageMustBeEncrypted = on; - } - - @Override - public void setReceivedMessagesMustBeSigned(boolean on) throws IOException { - this.receivedMessagesMustBeSigned = on; - } - - @Override - public void setSetAllowedRemotePeers(AllowedRemotePeers safetyLevel) { - - } - - @Override - public boolean setRevealEngineFormat(String peerName) { - return false; - } - - @Override - public boolean setSendOpenMessages(String peerName) { - return false; - } - - @Override - public boolean allowedToCreateChannel(ASAP_AssimilationPDU_1_0 asapAssimilationPDU) { - return true; // it is a dummy - } - - @Override - public void setSendEncryptedMessages(boolean on) { - this.sendEncrypted = on; - } - - @Override - public void setSendSignedMessages(boolean on) { - this.sendSigned = on; - } - - @Override - public boolean allowed2Process(ASAP_PDU_1_0 pdu) { - if(this.receivedMessagesMustBeSigned && !pdu.signed()) { - Log.writeLog(this, "checked: " + pdu); - Log.writeLog(this, "not signed"); - return false; - } - if(this.receivedMessageMustBeEncrypted && !pdu.encrypted()) { - Log.writeLog(this, "checked: " + pdu); - Log.writeLog(this, "not encrypted"); - return false; - } - - Log.writeLog(this, "ok"); - return true; - } - - private String getLogStart() { - return this.getClass().getSimpleName() + ": "; - } - - @Override - public boolean mustEncrypt() { - return this.sendEncrypted; - } - - @Override - public boolean mustSign() { - return this.sendSigned; - } - - /* - private boolean encryptedMessagesOnly = false; - private boolean signedMessagesOnly = false; - private boolean sendEncrypted = false; - private boolean sendSigned; - - */ - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogStart()); - sb.append("recEncrypted: " + this.receivedMessageMustBeEncrypted); - sb.append(" | recSigned: " + this.receivedMessagesMustBeSigned); - sb.append(" | sendEncrypted: " + this.sendEncrypted); - sb.append(" | sendSigned: " + this.sendSigned); - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/EngineSetting.java b/src/main/java/net/sharksystem/asap/engine/EngineSetting.java deleted file mode 100644 index 8316c27..0000000 --- a/src/main/java/net/sharksystem/asap/engine/EngineSetting.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap.engine; - -public class EngineSetting { - public final CharSequence folder; - public ASAPChunkAssimilatedListener listener; - public ASAPEngine engine; - - EngineSetting(CharSequence folder, ASAPChunkAssimilatedListener listener) { - this.folder = folder; - this.listener = listener; - } - - void setASAPEngine(ASAPEngine engine) { - this.engine = engine; - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/MessageIter.java b/src/main/java/net/sharksystem/asap/engine/MessageIter.java deleted file mode 100644 index 82eba0a..0000000 --- a/src/main/java/net/sharksystem/asap/engine/MessageIter.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.FileNotFoundException; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -public class MessageIter implements Iterator { - private final List byteMessages; - private int nextIndex; - private String nextString; - - - public MessageIter(List byteMessages) throws FileNotFoundException { - this.byteMessages = byteMessages; - this.nextIndex = 0; - } - - @Override - public boolean hasNext() { - return this.byteMessages.size() > nextIndex; - } - - @Override - public String next() { - if (!this.hasNext()) { - throw new NoSuchElementException("no more messages"); - } - - return new String(this.byteMessages.get(nextIndex++)); - } -} diff --git a/src/main/java/net/sharksystem/asap/engine/MessagesContainer.java b/src/main/java/net/sharksystem/asap/engine/MessagesContainer.java deleted file mode 100644 index 1e0f90e..0000000 --- a/src/main/java/net/sharksystem/asap/engine/MessagesContainer.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPHop; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -public interface MessagesContainer { - void addMessage(InputStream is, long length) throws IOException; - void setASAPHopList(List asapHopList) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/ASAPChannelContentChangedListenerManager.java b/src/main/java/net/sharksystem/asap/listenermanager/ASAPChannelContentChangedListenerManager.java deleted file mode 100644 index 00beaa7..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/ASAPChannelContentChangedListenerManager.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.sharksystem.asap.listenermanager; - -import net.sharksystem.asap.*; - -import java.util.HashMap; - -public class ASAPChannelContentChangedListenerManager implements ASAPChannelContentChangedListenerManagement { - private HashMap> listenerMap = - new HashMap(); - - @Override - public void addASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener) { - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList == null) { - listenerList = new GenericListenerImplementation(); - this.listenerMap.put(format, listenerList); - } - - listenerList.addListener(listener); - } - - @Override - public void removeASAPChannelContentChangedListener(CharSequence format, ASAPChannelContentChangedListener listener) { - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList != null) { - listenerList.removeListener(listener); - } - } - - public int getNumberListener() { - if(this.listenerMap == null) return 0; - return this.listenerMap.size(); - } - - public void removeAllListeners() { - // reset - this.listenerMap = new HashMap(); - } - - public void notifyChanged(CharSequence format, CharSequence uri, int era) { - - this.notifyChanged(format, uri, era, false); - } - - public void notifyChanged(CharSequence format, CharSequence uri, int era, boolean useThreads) { - - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList != null) { - ASAPChannelContentChangedListenerManager.ASAPChannelContentChangedNotifier notifier - = new ASAPChannelContentChangedListenerManager.ASAPChannelContentChangedNotifier(format, uri, era); - - listenerList.notifyAll(notifier, useThreads); - } - } - - public class ASAPChannelContentChangedNotifier implements GenericNotifier { - private CharSequence format; - private CharSequence uri; - private int era; - - ASAPChannelContentChangedNotifier(CharSequence format, CharSequence uri, int era) { - this.format = format; - this.uri = uri; - this.era = era; - } - - public void doNotify(ASAPChannelContentChangedListener listener) { - listener.asapChannelContentChanged(this.format, this.uri, this.era); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/ASAPEnvironmentChangesListenerManager.java b/src/main/java/net/sharksystem/asap/listenermanager/ASAPEnvironmentChangesListenerManager.java deleted file mode 100644 index 6d54f61..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/ASAPEnvironmentChangesListenerManager.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sharksystem.asap.listenermanager; - -import net.sharksystem.asap.ASAPEnvironmentChangesListener; -import net.sharksystem.asap.ASAPEnvironmentChangesListenerManagement; -import net.sharksystem.utils.Log; - -import java.util.HashSet; -import java.util.Set; - -public class ASAPEnvironmentChangesListenerManager - extends GenericListenerImplementation - implements ASAPEnvironmentChangesListenerManagement { - - @Override - public void addASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener) { - this.addListener(changesListener); - } - - @Override - public void removeASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener) { - this.removeListener(changesListener); - } - - public void notifyListeners(Set peerList) { - if(peerList == null) peerList = new HashSet<>(); - - if(this.listenerList == null || this.listenerList.isEmpty()) return; - - // make a copy of that list - for(ASAPEnvironmentChangesListener listener : this.listenerList) { - if(listener != null) listener.onlinePeersChanged(new HashSet<>(peerList)); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/ASAPMessageReceivedListenerManager.java b/src/main/java/net/sharksystem/asap/listenermanager/ASAPMessageReceivedListenerManager.java deleted file mode 100644 index 41de9d0..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/ASAPMessageReceivedListenerManager.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.sharksystem.asap.listenermanager; - -import net.sharksystem.asap.*; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; - -public class ASAPMessageReceivedListenerManager implements ASAPMessageReceivedListenerManagement { - private HashMap> listenerMap = - new HashMap(); - - @Override - public void addASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener) { - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList == null) { - listenerList = new GenericListenerImplementation(); - this.listenerMap.put(format, listenerList); - } - - listenerList.addListener(listener); - } - - @Override - public void removeASAPMessageReceivedListener(CharSequence format, ASAPMessageReceivedListener listener) { - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList != null) { - listenerList.removeListener(listener); - } - } - - @Override - public int getNumberListener() { - if(this.listenerMap == null) return 0; - return this.listenerMap.size(); - } - - public void removeAllListeners() { - // reset - this.listenerMap = new HashMap(); - } - - public void notifyReceived(CharSequence format, ASAPMessages asapMessage, - String senderE2E, // E2E part - List asapHopList) { - - this.notifyReceived(format, asapMessage, false, senderE2E, asapHopList); - } - - public void notifyReceived(CharSequence format, ASAPMessages asapMessage, boolean useThreads, - String senderE2E, List asapHopList) { - - GenericListenerImplementation listenerList = this.listenerMap.get(format); - if(listenerList != null) { - ASAPMessageReceivedNotifier asapMessageReceivedNotifier - = new ASAPMessageReceivedNotifier(asapMessage, senderE2E, asapHopList); - - listenerList.notifyAll(asapMessageReceivedNotifier, useThreads); - } - } - - public class ASAPMessageReceivedNotifier implements GenericNotifier { - private final ASAPMessages asapMessage; - private final String senderE2E; - private List asapHopList; - - ASAPMessageReceivedNotifier(ASAPMessages asapMessage, - String senderE2E, - List asapHopList) { - - this.asapMessage = asapMessage; - this.senderE2E = senderE2E; - this.asapHopList = asapHopList; - } - - public void doNotify(ASAPMessageReceivedListener listener) { - try { - //Log.writeLog(this, "notify: " + listener.getClass().getSimpleName()); - listener.asapMessagesReceived(this.asapMessage, this.senderE2E, this.asapHopList); - } catch (IOException e) { - System.err.println("error when notifying about received asap message: " - + e.getLocalizedMessage()); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/net/sharksystem/asap/listenermanager/GenericListenerImplementation.java b/src/main/java/net/sharksystem/asap/listenermanager/GenericListenerImplementation.java deleted file mode 100644 index e2d4507..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/GenericListenerImplementation.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.sharksystem.asap.listenermanager; - -import net.sharksystem.utils.Log; - -import java.util.ArrayList; -import java.util.List; - -public class GenericListenerImplementation { - protected List listenerList = new ArrayList(); - - protected void addListener(L listener) { - if(!this.listenerList.contains(listener)) { - this.listenerList.add(listener); - } - } - - protected void removeListener(L listener) { - this.listenerList.remove(listener); - } - - public void removeAllListeners() { - this.listenerList = new ArrayList(); - } - - public void notifyAll(GenericNotifier notifier, boolean useThreads) { - for(L listener : this.listenerList) { - if(useThreads) { - new Thread (new Runnable() { - @Override - public void run() { notifier.doNotify(listener); } - }).start(); - } else { // no threads - notifier.doNotify(listener); - } - } - } - - protected void log(String msg) { - StringBuilder sb = new StringBuilder(); - sb.append(Log.startLog(this)); - sb.append(": "); - sb.append(msg); - - Log.writeLog(this, sb.toString()); - } - -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/GenericNotifier.java b/src/main/java/net/sharksystem/asap/listenermanager/GenericNotifier.java deleted file mode 100644 index 9bd2fa5..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/GenericNotifier.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.sharksystem.asap.listenermanager; - -public interface GenericNotifier { - /** - * run specific notification - */ - void doNotify(L listener); -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementCreateASAPStorageMessage.java b/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementCreateASAPStorageMessage.java deleted file mode 100644 index 2e813ae..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementCreateASAPStorageMessage.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.sharksystem.asap.listenermanager.management; - -import java.util.Set; - -public interface ASAPManagementCreateASAPStorageMessage { - /** - * @return list of recipients of this storage/channel - */ - Set getRecipients(); - - /** - * @return channel uri - */ - CharSequence getChannelUri(); - - /** - * - * @return storage/channel owner - */ - CharSequence getOwner(); - - CharSequence getAppName(); -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessage.java b/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessage.java deleted file mode 100644 index 8bef338..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessage.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.sharksystem.asap.listenermanager.management; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.asap.protocol.ASAP_PDU_1_0; - -import java.io.*; -import java.util.*; - -public class ASAPManagementMessage { - public static byte[] getCreateClosedASAPChannelMessage( - CharSequence owner, CharSequence appName, CharSequence channelUri, - Collection recipients) throws ASAPException, IOException { - - if(recipients == null || recipients.size() < 1) { - throw new ASAPException("recipients in storage/channelUri must not be null or empty: "); - } - - // we have to put format and recipients into an assimilate message. - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - - // put owner - dos.writeUTF(owner.toString()); - - // put appName uri - dos.writeUTF(appName.toString()); - - // put channelUri uri - dos.writeUTF(channelUri.toString()); - - // put recipients - for(CharSequence recipient : recipients) { - dos.writeUTF(recipient.toString()); - } - - return baos.toByteArray(); - } - - public static ASAPManagementCreateASAPStorageMessage parseASAPManagementMessage(byte[] message) - throws IOException { - - return new CreateASAPStorageMessage(message); - } - - private static boolean isASAPManagementMessage(ASAP_PDU_1_0 asapPDU) { - return asapPDU.getFormat().equalsIgnoreCase(ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - } - - private static class CreateASAPStorageMessage implements ASAPManagementCreateASAPStorageMessage { - private final Set recipients; - private final CharSequence channelUri; - private final CharSequence appName; - private final CharSequence owner; - - CreateASAPStorageMessage(byte[] message) throws IOException { - - // convert to string - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(message)); - this.owner = dis.readUTF(); - this.appName = dis.readUTF(); - this.channelUri = dis.readUTF(); - - // there must be at least one recipient - this.recipients = new HashSet<>(); - this.recipients.add(dis.readUTF()); - - // and maybe some more - try { - for(;;) { - this.recipients.add(dis.readUTF()); - } - } - catch(Throwable t) { - // reach end - ok - } - } - - @Override - public Set getRecipients() { - return this.recipients; - } - - @Override - public CharSequence getChannelUri() { - return this.channelUri; - } - - @Override - public CharSequence getOwner() { - return this.owner; - } - - @Override - public CharSequence getAppName() { - return this.appName; - } - } -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessageHandler.java b/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessageHandler.java deleted file mode 100644 index fa91269..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementMessageHandler.java +++ /dev/null @@ -1,167 +0,0 @@ -package net.sharksystem.asap.listenermanager.management; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.engine.ASAPInternalChunk; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalStorage; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.engine.*; -import net.sharksystem.asap.protocol.ASAP_1_0; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.*; - -public class ASAPManagementMessageHandler implements ASAPChunkAssimilatedListener { - private final ASAPInternalPeer multiASAPEngine; - - public ASAPManagementMessageHandler(ASAPInternalPeer multiASAPEngine) throws IOException, ASAPException { - this.multiASAPEngine = multiASAPEngine; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////// - // chunk received listener for asap management engine // - /////////////////////////////////////////////////////////////////////////////////////////////////////// - - private HashMap, CharSequence> recipientUris = new HashMap<>(); - - public static CharSequence createUniqueUri() { - return "sn2://asapManagement://" + Long.toString(System.currentTimeMillis()); - } - - CharSequence getURI(Set recipients) throws IOException, ASAPException { - // find entry with all recipients - and only those recipients - - for(Set rSet : recipientUris.keySet()) { - // are recipients fully inside rSet? - if(rSet.containsAll(recipients) && recipients.containsAll(rSet)) { - return recipientUris.get(rSet); - } - } - - return null; - } - - @Override - public void chunkStored(String format, String senderE2E, String uri, int era, - List asapHop) throws IOException { - - Log.writeLog(this, - "handle received chunk (format|senderE2E|uri|era) " + format + senderE2E + "|" + uri + "|" + era); - try { - ASAPEngine asapManagementEngine = multiASAPEngine.getEngineByFormat(ASAP_1_0.ASAP_MANAGEMENT_FORMAT); - - ASAPChunkStorage incomingChunkStorage = asapManagementEngine.getReceivedChunksStorage(senderE2E); - ASAPInternalChunk chunk = incomingChunkStorage.getChunk(uri, era); - Iterator messageIter = chunk.getMessages(); - Log.writeLog(this, "iterate management messages"); - while(messageIter.hasNext()) { - byte[] message = messageIter.next(); - Set recipients = this.handleASAPManagementMessage(message); - - // add message without changes - could be signed - CharSequence sendUri = this.getURI(recipients); - boolean setUpRecipients = (sendUri == null); - if(setUpRecipients) { - sendUri = createUniqueUri(); - } - // write message - Log.writeLog(this, "add received message locally: "); - asapManagementEngine.add(sendUri, message); - - if(setUpRecipients) { - asapManagementEngine.setRecipients(sendUri, recipients); - this.recipientUris.put(recipients, sendUri); - } - } - Log.writeLog(this, "done iterating management messages"); - // remove incoming messages - handled - asapManagementEngine.getReceivedChunksStorage(senderE2E).dropChunks(era); - Log.writeLog(this, "incoming asap management messages dropped"); - } catch (ASAPException | IOException e) { - Log.writeLog(this, "could get asap management engine but received chunk - looks like a bug"); - } - } - - @Override - public void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException { - Log.writeLogErr(this, "transientChunkReceived not yet implement"); - } - - private Set handleASAPManagementMessage(byte[] message) throws ASAPException, IOException { - StringBuilder b = new StringBuilder(); - b.append(this.getLogStart()); - b.append("start processing asap management pdu"); - Log.writeLog(this, b.toString()); - - ASAPManagementCreateASAPStorageMessage asapManagementCreateASAPStorageMessage = - ASAPManagementMessage.parseASAPManagementMessage(message); - - CharSequence owner = asapManagementCreateASAPStorageMessage.getOwner(); - CharSequence channelUri = asapManagementCreateASAPStorageMessage.getChannelUri(); - CharSequence format = asapManagementCreateASAPStorageMessage.getAppName(); - Set receivedRecipients = asapManagementCreateASAPStorageMessage.getRecipients(); - - // add owner to this list - Set recipients = new HashSet<>(); - - // add owner - recipients.add(owner); - - // add rest - for(CharSequence r : receivedRecipients) { - recipients.add(r); - } - - b = new StringBuilder(); - b.append(this.getLogStart()); - b.append("owner: "); - b.append(owner); - b.append(" | format: "); - b.append(format); - b.append(" | channelUri: "); - b.append(channelUri); - b.append(" | #recipients: "); - b.append(recipients.size()); - - // find storage / app - can throw an exception - that's ok - ASAPInternalStorage asapStorage = this.multiASAPEngine.getEngineByFormat(format); - - if(asapStorage.channelExists(channelUri)) { - Set existingChannelRecipientsList = asapStorage.getRecipients(channelUri); - if(existingChannelRecipientsList.size() == recipients.size()) { - // could be the same - same recipients? - - // iterate all recipient and check whether they are also in local recipient list - for(CharSequence recipient : recipients) { - boolean found = false; - for(CharSequence existingRecipient : existingChannelRecipientsList) { - if(existingRecipient.toString().equalsIgnoreCase(recipient.toString())) { - // got it - found = true; - break; // leave loop and test next - } - } - if(!found) { - throw new ASAPException("channel already exists but with different recipients: " + b.toString()); - } - } - // ok it the same - return receivedRecipients; - } else { - throw new ASAPException("channel already exists but with different settings: " + b.toString()); - } - } - - // else - channel does not exist - create by setting recipients - Log.writeLog(this, "create channel: " + b.toString()); - asapStorage.createChannel(owner, channelUri, recipients); - - return receivedRecipients; - } - - private String getLogStart() { - return this.getClass().getSimpleName() + "(" + this.multiASAPEngine.getOwner() + "): "; - } -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorage.java b/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorage.java deleted file mode 100644 index 93cf6a6..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorage.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sharksystem.asap.listenermanager.management; - -import net.sharksystem.asap.ASAPException; - -import java.io.IOException; -import java.util.Collection; - -public interface ASAPManagementStorage { - CharSequence ASAP_CREATE_CHANNEL = "asap://createChannel"; - - void notifyChannelCreated(CharSequence appName, CharSequence channelUri, - CharSequence uri, Collection storageRecipients) throws ASAPException, IOException; -} diff --git a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorageImpl.java b/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorageImpl.java deleted file mode 100644 index 17c8408..0000000 --- a/src/main/java/net/sharksystem/asap/listenermanager/management/ASAPManagementStorageImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.sharksystem.asap.listenermanager.management; - -import net.sharksystem.asap.engine.ASAPEngine; -import net.sharksystem.asap.ASAPException; - -import java.io.IOException; -import java.util.Collection; - -public class ASAPManagementStorageImpl implements ASAPManagementStorage { - private final ASAPEngine asapEngine; - - public ASAPManagementStorageImpl(ASAPEngine asapEngine) { - this.asapEngine = asapEngine; - } - - @Override - public void notifyChannelCreated(CharSequence appName, CharSequence channelUri, CharSequence uri, - Collection recipients) throws ASAPException, IOException { - - byte[] createClosedASAPChannelMessage = ASAPManagementMessage.getCreateClosedASAPChannelMessage( - this.asapEngine.getOwner(), - appName, - uri, - recipients); - - // put into a channel - CharSequence newUri = ASAPManagementMessageHandler.createUniqueUri(); - this.asapEngine.add(newUri, createClosedASAPChannelMessage); - this.asapEngine.setRecipients(newUri, recipients); - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPConnection.java b/src/main/java/net/sharksystem/asap/protocol/ASAPConnection.java deleted file mode 100644 index 8f66e66..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPConnection.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPEncounterConnectionType; - -public interface ASAPConnection { - CharSequence getEncounteredPeer(); - - void addOnlineMessageSource(ASAPOnlineMessageSource source); - void removeOnlineMessageSource(ASAPOnlineMessageSource source); - - void addASAPConnectionListener(ASAPConnectionListener asapConnectionListener); - - void removeASAPConnectionListener(ASAPConnectionListener asapConnectionListener); - - boolean isSigned(); - - ASAPEncounterConnectionType getASAPEncounterConnectionType(); - - // terminate that connection - does not effect the underlying connections established e.g. with Bluetooth - void kill(); -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPConnectionListener.java b/src/main/java/net/sharksystem/asap/protocol/ASAPConnectionListener.java deleted file mode 100644 index f7abfc5..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPConnectionListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.sharksystem.asap.protocol; - -public interface ASAPConnectionListener { - /** - * Called when first message was read from remote peer. - * The session started. - */ - void asapConnectionStarted(String remotePeerName, ASAPConnection connection); - - void asapConnectionTerminated(Exception terminatingException, ASAPConnection connection); -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPCryptoMessage.java b/src/main/java/net/sharksystem/asap/protocol/ASAPCryptoMessage.java deleted file mode 100644 index de76424..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPCryptoMessage.java +++ /dev/null @@ -1,228 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.asap.crypto.ASAPCryptoAlgorithms; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.utils.Log; - -import java.io.*; - -class ASAPCryptoMessage { - private boolean encrypted; - private boolean sign; - private CharSequence recipient; - private ASAPKeyStore ASAPKeyStore; - private byte cmd; - - private OutputStream effectiveOS; - private OutputStream realOS; - private ByteArrayOutputStream outputStreamCopy; - private InputStreamCopy inputStreamCopy; - private ASAPCryptoAlgorithms.EncryptedMessagePackage encryptedMessagePackage; - - ASAPCryptoMessage(ASAPKeyStore ASAPKeyStore) { - this.ASAPKeyStore = ASAPKeyStore; - } - - ASAPCryptoMessage(byte cmd, OutputStream os, boolean sign, boolean encrypted, - CharSequence recipient, - ASAPKeyStore ASAPKeyStore) - throws ASAPSecurityException { - - this.cmd = cmd; - this.realOS = os; - this.effectiveOS = os; // still this one - this.ASAPKeyStore = ASAPKeyStore; - this.recipient = recipient; - this.encrypted = encrypted; - this.sign = sign; - - if(encrypted || sign) { - // we need some basic crypto parameters - if(ASAPKeyStore == null) { - throw new ASAPSecurityException("cannot encrypt or sign without cryptp parameters / key store"); - } - this.setupCopyOutputStream(); - } - - if(encrypted) { - // mark encryption in command - rest will be encrypted - this.cmd += ASAP_1_0.ENCRYPTED_CMD; - if(this.recipient == null) { - throw new ASAPSecurityException("cannot encrypt message with no specified receiver - fatal, give up"); - } - } - - if(sign) { - // signing needs a private key - check of available - if(ASAPKeyStore.getPrivateKey() == null) { - throw new ASAPSecurityException("asap message is to be signed but no private key - fatal, give up"); - } - } - } - - private void setupCopyOutputStream() { - if(this.outputStreamCopy == null) { - this.outputStreamCopy = new ByteArrayOutputStream(); - // pud will make a detour - this.effectiveOS = this.outputStreamCopy; - } - } - - public void sendCmd() throws IOException { - // send cmd in clear - PDU_Impl.sendCmd(this.cmd, this.realOS); - } - - public OutputStream getOutputStream() { - return this.effectiveOS; - } - - public void finish() throws ASAPSecurityException { - if(this.sign) { - try { - // get message as bytes - byte[] asapMessageAsBytes = this.outputStreamCopy.toByteArray(); - // produce signature - byte[] signatureBytes = ASAPCryptoAlgorithms.sign(asapMessageAsBytes, this.ASAPKeyStore); - - if(this.encrypted) { - // have to store it - message and signature will be encrypted - ASAPSerialization.writeByteArray(signatureBytes, this.outputStreamCopy); - } else { - // no encryption planned - write clear to stream - this.realOS.write(asapMessageAsBytes); - ASAPSerialization.writeByteArray(signatureBytes, this.realOS); - } - } catch (IOException e) { - throw new ASAPSecurityException(this.getLogStart(), e); - } - } - - if(this.encrypted) { - // get maybe signed asap message - byte[] asapMessageAsBytes = this.outputStreamCopy.toByteArray(); - - ASAPCryptoAlgorithms.writeEncryptedMessagePackage( - asapMessageAsBytes, this.recipient, this.ASAPKeyStore, this.realOS); - } - } - - public CharSequence getReceiver() { - return this.recipient; - } - - ////////////////////////////////// verify - private class InputStreamCopy extends InputStream { - private final InputStream is; - ByteArrayOutputStream copy = new ByteArrayOutputStream(); - - InputStreamCopy(byte[] bytes, InputStream is) throws IOException { - // add byte if any - if(bytes != null && bytes.length > 0) { - copy.write(bytes); - } - - this.is = is; - } - - @Override - public int read() throws IOException { - int read = is.read(); - copy.write(read); - return read; - } - - byte[] getCopy() { - return copy.toByteArray(); - } - } - - public InputStream setupCopyInputStream(int flags, InputStream is) - throws IOException { - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); -// if(writeInt) { -// PDU_Impl.sendFlags(flags, baos); -// } - - PDU_Impl.sendFlags(flags, baos); - //baos.write(flags); - - this.inputStreamCopy = new InputStreamCopy(baos.toByteArray(), is); - return this.inputStreamCopy; - } - - public boolean verify(String sender, InputStream is) throws IOException, ASAPException { - // try to get senders' public key - byte[] signedData = this.inputStreamCopy.getCopy(); - byte[] signatureBytes = ASAPSerialization.readByteArray(is); - // debug break - boolean wasVerified = - ASAPCryptoAlgorithms.verify(signedData, signatureBytes, sender, this.ASAPKeyStore); - - return wasVerified; - } - - ////////////////////////////////// decrypt - - /** - * Simple idea: We read anything from stream and keep a copy. Later, we figure out - * if we can encrypt that message or not. Either way, we can keep and redistribute a copy. - * - * - * @param cmd - * @param is - * @return - * @throws IOException - * @throws ASAPException - */ - public boolean initDecryption(byte cmd, InputStream is) throws IOException, ASAPException { - // make a copy of encrypted message - it is redundant. Same data in encryptedMessagePackage - //InputStream copyStream = this.setupCopyInputStream(cmd, is); - - this.encryptedMessagePackage = - ASAPCryptoAlgorithms.parseEncryptedMessagePackage(is); - // ASAPCryptoAlgorithms.parseEncryptedMessagePackage(copyStream); - - if(this.ASAPKeyStore == null) { - Log.writeLog(this, "no keystore set: cannot handle encrypted messages"); - return false; - } - - if(this.ASAPKeyStore.isOwner(this.encryptedMessagePackage.getReceiver())) { - return true; - } - - return false; - } - - ASAPCryptoAlgorithms.EncryptedMessagePackage getEncryptedMessage() throws ASAPSecurityException { - return this.encryptedMessagePackage; - /* - if(this.inputStreamCopy == null) { - throw new ASAPSecurityException( - this.getLogStart() + "no copy made, maybe forgot to initialize decryption?"); - } - - return this.inputStreamCopy.getCopy(); - */ - } - - public InputStream doDecryption() throws ASAPSecurityException { - if(this.encryptedMessagePackage == null) { - throw new ASAPSecurityException("forgot to initialize decryption? There are no data"); - } - - byte[] decryptedBytes = - ASAPCryptoAlgorithms.decryptPackage(this.encryptedMessagePackage, this.ASAPKeyStore); - - return new ByteArrayInputStream(decryptedBytes); - } - - private String getLogStart() { - return this.getClass().getSimpleName() + ": "; - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPEncounterList.java b/src/main/java/net/sharksystem/asap/protocol/ASAPEncounterList.java deleted file mode 100644 index 2729637..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPEncounterList.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; - -import java.io.IOException; -import java.util.Set; - -public interface ASAPEncounterList { - /** - * Provides a set of peer id. There is record of a previous encounter with those peers. - * @return - */ - Set getEncounteredPeers(); - - /** - * Provide era of last encounter with a peer. The local era, the counting of this peer is returned. - * @param peerID - * @return - * @throws ASAPException There is not such peerID - */ - int getLocalMostRecentEra(CharSequence peerID) throws ASAPException; - - /** - * Provide the most era from a most recent chunk received by this peer. - * @param peerID - * @return - * @throws ASAPException There is not such peerID - */ - int getTheirMostRecentEra(CharSequence peerID) throws ASAPException, IOException; -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPExecTimeExceededException.java b/src/main/java/net/sharksystem/asap/protocol/ASAPExecTimeExceededException.java deleted file mode 100644 index f9b0ebb..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPExecTimeExceededException.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; - -public class ASAPExecTimeExceededException extends ASAPException { - public ASAPExecTimeExceededException() { - super(); - } - - public ASAPExecTimeExceededException(String message) { - super(message); - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPOnlineMessageSource.java b/src/main/java/net/sharksystem/asap/protocol/ASAPOnlineMessageSource.java deleted file mode 100644 index d5c9a5f..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPOnlineMessageSource.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.sharksystem.asap.protocol; - -import java.io.IOException; -import java.io.OutputStream; - -public interface ASAPOnlineMessageSource { - void sendStoredMessages(ASAPConnection asapConnection, OutputStream os) throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPProtocolEngine.java b/src/main/java/net/sharksystem/asap/protocol/ASAPProtocolEngine.java deleted file mode 100644 index 35166f1..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPProtocolEngine.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.engine.ASAPUndecryptableMessageHandler; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public abstract class ASAPProtocolEngine { - protected final ASAP_1_0 protocol; - protected final InputStream is; - protected final OutputStream os; - protected final ASAPUndecryptableMessageHandler undecryptableMessageHandler; - protected final ASAPKeyStore ASAPKeyStore; - - public ASAPProtocolEngine(InputStream is, OutputStream os, ASAP_1_0 protocol, - ASAPUndecryptableMessageHandler undecryptableMessageHandler, - ASAPKeyStore ASAPKeyStore) { - /* - this.is = new ISWrapper(is); - this.os = new OSWrapper(os); - */ - this.is = is; - this.os = os; - this.protocol = protocol; - this.undecryptableMessageHandler = undecryptableMessageHandler; - this.ASAPKeyStore = ASAPKeyStore; - - Log.writeLog(this, "constructor", "is: " - + is.getClass().getSimpleName() + " | os: " + os.getClass().getSimpleName()); - } - - private class ISWrapper extends InputStream { - private final InputStream is; - - ISWrapper(InputStream is) { - this.is = is; - } - @Override - public int read() throws IOException { - return is.read(); - } - public void close() { - Log.writeLog(this, "wrapper: close called"); - } - } - - private class OSWrapper extends OutputStream { - private final OutputStream os; - - OSWrapper(OutputStream is) { - this.os = is; - } - - @Override - public void write(int b) throws IOException { - this.os.write(b); - } - - public void close() { - Log.writeLog(this, "wrapper: close called"); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAPSessionImpl.java b/src/main/java/net/sharksystem/asap/protocol/ASAPSessionImpl.java deleted file mode 100644 index b149a29..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAPSessionImpl.java +++ /dev/null @@ -1,557 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPEngine; -import net.sharksystem.asap.engine.ASAPInternalPeer; -import net.sharksystem.asap.engine.ASAPUndecryptableMessageHandler; -import net.sharksystem.asap.engine.EngineSetting; -import net.sharksystem.utils.Log; -import net.sharksystem.asap.crypto.ASAPKeyStore; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -public class ASAPSessionImpl extends ASAPProtocolEngine - implements ASAPConnection, Runnable, ThreadFinishedListener { - - private final List asapConnectionListener; - private final ASAPInternalPeer asapInternalPeer; - private final ThreadFinishedListener threadFinishedListener; - private final boolean encrypt; - private final boolean sign; - private final ASAPEncounterConnectionType connectionType; - private Thread managementThread = null; - private final long maxExecutionTime; - private String encounteredPeer; - - private List onlineMessageSources = new ArrayList<>(); - private Thread threadWaiting4StreamsLock; - private boolean terminated = false; - - public ASAPSessionImpl(InputStream is, OutputStream os, ASAPInternalPeer asapInternalPeer, - ASAP_1_0 protocol, ASAPUndecryptableMessageHandler unencryptableMessageHandler, - ASAPKeyStore ASAPKeyStore, - long maxExecutionTime, ASAPConnectionListener asapConnectionListener, - ThreadFinishedListener threadFinishedListener, - boolean encrypt, boolean sign, ASAPEncounterConnectionType connectionType) { - - super(is, os, protocol, unencryptableMessageHandler, ASAPKeyStore); - - this.asapInternalPeer = asapInternalPeer; - this.maxExecutionTime = maxExecutionTime; - this.asapConnectionListener = new ArrayList<>(); - this.asapConnectionListener.add(asapConnectionListener); - - this.threadFinishedListener = threadFinishedListener; - this.encrypt = encrypt; - this.sign = sign; - this.connectionType = connectionType; - } - - public void addASAPConnectionListener(ASAPConnectionListener asapConnectionListener) { - this.asapConnectionListener.add(asapConnectionListener); - } - - public void removeASAPConnectionListener(ASAPConnectionListener asapConnectionListener) { - this.asapConnectionListener.remove(asapConnectionListener); - } - - private String getLogParameter() { - String s = "to: "; - s += this.encounteredPeer != null ? this.encounteredPeer : "unknown yet"; - return s; - } - - private void setEncounteredPeer(String remotePeerName) { - if(this.encounteredPeer == null) { - - this.encounteredPeer = remotePeerName; - - StringBuilder sb = new StringBuilder(); - sb.append(this.getLogParameter()); - sb.append("set remotePeerName after reading first asap message: "); - sb.append(remotePeerName); - Log.startLog(this, sb.toString()); - - if(this.asapConnectionListener != null) { - for(ASAPConnectionListener l : this.asapConnectionListener) { - l.asapConnectionStarted(remotePeerName, this); - } - } - } - } - - @Override - public CharSequence getEncounteredPeer() { - return this.encounteredPeer; - } - - @Override - public void removeOnlineMessageSource(ASAPOnlineMessageSource source) { - this.onlineMessageSources.remove(source); - } - - public boolean isSigned() { - return false; - } - - @Override - public ASAPEncounterConnectionType getASAPEncounterConnectionType() { - return this.connectionType; - } - - @Override - public void kill() { - this.kill(new ASAPException("kill called from outside asap connection")); - } - - public void kill(Exception e) { - if(!this.terminated) { - this.terminated = true; - // kill reader - proved to be useful in a bluetooth environment - if(this.pduReader != null && this.pduReader.isAlive()) { - this.pduReader.interrupt(); - } - if(this.managementThread != null && this.managementThread.isAlive()) { - this.managementThread.interrupt(); - } - // inform listener - if (this.asapConnectionListener != null) { - for(ASAPConnectionListener l : this.asapConnectionListener) { - l.asapConnectionTerminated(e, this); - } - } - - if (this.threadFinishedListener != null) { - this.threadFinishedListener.finished(Thread.currentThread()); - } - } - } - - @Override - public void finished(Thread t) { - if(this.managementThread != null) { - this.managementThread.interrupt(); - } - } - - private void terminate(String message, Throwable t) { - // write log - StringBuilder sb = new StringBuilder(); - sb.append(message); - if(t != null) { - sb.append(" | issued by: "); - sb.append(t.getClass().getSimpleName()); - sb.append(": "); - sb.append(t.getLocalizedMessage()); - // debugging - //t.printStackTrace(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - t.printStackTrace(new PrintStream(baos)); - sb.append("\n>>>>>>>>>>>>> stack trace:\n"); - sb.append(baos.toString()); - sb.append("<<<<<<<<<<<< stack trace"); - } - Log.writeLog(this, this.getLogParameter(), sb.toString()); - - this.kill(); - } - - private void sendOnlineMessages() throws IOException { - List copy = this.onlineMessageSources; - this.onlineMessageSources = new ArrayList<>(); - while(!copy.isEmpty()) { - ASAPOnlineMessageSource asapOnline = copy.remove(0); - StringBuilder sb = new StringBuilder(); - sb.append("going to send online message"); - Log.writeLog(this, this.getLogParameter(), sb.toString()); - asapOnline.sendStoredMessages(this, this.os); - } - } - - private class OnlineMessageSenderThread extends Thread { - public void run() { - try { - // get exclusive access to streams - Log.writeLog(this, getLogParameter(), "online sender is going to wait for stream access"); - wait4ExclusiveStreamsAccess(); - Log.writeLog(this, getLogParameter(), "online sender got stream access"); - sendOnlineMessages(); - // prepare a graceful death - onlineMessageSenderThread = null; - // are new message waiting in the meantime? - checkRunningOnlineMessageSender(); - } catch (IOException e) { - terminate("could not write data into stream", e); - } - finally { - Log.writeLog(this, getLogParameter(), "online sender releases lock"); - releaseStreamsLock(); - } - } - } - - private OnlineMessageSenderThread onlineMessageSenderThread = null; - private ASAPPDUReader pduReader = null; - Thread executor = null; - - @Override - public void addOnlineMessageSource(ASAPOnlineMessageSource source) { - this.onlineMessageSources.add(source); - this.checkRunningOnlineMessageSender(); - } - - private synchronized void checkRunningOnlineMessageSender() { - if(this.onlineMessageSenderThread == null - && this.onlineMessageSources != null && this.onlineMessageSources.size() > 0) { - this.onlineMessageSenderThread = new OnlineMessageSenderThread(); - this.onlineMessageSenderThread.start(); - } - } - - public void run() { - ASAP_1_0 protocol = new ASAP_Modem_Impl(this.ASAPKeyStore, this.undecryptableMessageHandler); - - try { - // let engine write their interest - at least management interest is sent which als introduces - // this peer to the other one - this.asapInternalPeer.pushInterests(this.os); - } catch (IOException | ASAPException e) { - this.terminate("error when pushing interest: ", e); - //e.printStackTrace(); - return; - } - - /////////////////////////////// read - while (!this.terminated) { - this.pduReader = new ASAPPDUReader(protocol, is, this); - Throwable unexpectedThrowable = null; - try { - Log.writeLog(this, this.getLogParameter(), "start reading"); - this.runObservedThread(pduReader, this.maxExecutionTime); - } catch (ASAPExecTimeExceededException e) { - Log.writeLog(this, this.getLogParameter(), "reading on stream took longer than allowed"); - } - catch(Throwable t) { - unexpectedThrowable = t; - Log.writeLog(this, this.getLogParameter(), "while reading PDU: " - + t.getClass().getSimpleName() + ": " + t.getLocalizedMessage()); - } - - Log.writeLog(this, this.getLogParameter(), "back from reading"); - if(terminated) break; // thread could be killed in the meantime - - if (unexpectedThrowable != null || pduReader.getIoException() != null || pduReader.getAsapException() != null) { - Log.writeLog(this, this.getLogParameter(), "connection broken"); - - Throwable problem = pduReader.getIoException() != null ? - pduReader.getIoException() : pduReader.getAsapException(); - - if(problem == null) problem = unexpectedThrowable; - - try { - Log.writeLog(this, this.getLogParameter(), "close input stream"); - this.is.close(); - } catch (IOException exception) { - Log.writeLog(this, this.getLogParameter(), - "tried to close stream after exception caught: " + exception.getLocalizedMessage()); - } - - this.terminate("problem when reading from stream (close asap session and stream): ", problem); - break; - } - - ASAP_PDU_1_0 asappdu = pduReader.getASAPPDU(); - /////////////////////////////// process - if(asappdu != null) { - Log.writeLog(this, this.getLogParameter(), - "read valid pdu, remember meeting this peer and going to process pdu"); - this.setEncounteredPeer(asappdu.getSender()); - - EngineSetting engineSettings = null; - try { - engineSettings = this.asapInternalPeer.getEngineSettings(asappdu.getFormat()); - } catch(ASAPException e) { - // can happen with transient messages - Log.writeLog(this, this.getLogParameter(), "no engine setting - set defaults"); - } - - try { - if(engineSettings == null) { - ASAPEngine asapEngine = this.asapInternalPeer.getASAPEngine(asappdu.getFormat()); - engineSettings = this.asapInternalPeer.getEngineSettings(asappdu.getFormat()); - engineSettings.engine = asapEngine; - Log.writeLog(this, this.getLogParameter(), engineSettings.toString()); - } - - this.executor = new ASAPPDUExecutor(asappdu, - this.encounteredPeer, this.is, this.os, engineSettings, - protocol,this.connectionType, this); - - // get exclusive access to streams - Log.writeLog(this, this.getLogParameter(), "asap pdu executor going to wait for stream access"); - this.wait4ExclusiveStreamsAccess(); - try { - Log.writeLog(this, this.getLogParameter(), "asap pdu executor got stream access - process pdu"); - this.runObservedThread(executor, maxExecutionTime); - } catch (ASAPExecTimeExceededException e) { - Log.writeLog(this, this.getLogParameter(), "asap pdu processing took longer than allowed"); - this.terminate("asap pdu processing took longer than allowed", e); - break; - } finally { - // wake waiting thread if any - this.releaseStreamsLock(); - Log.writeLog(this, this.getLogParameter(), "asap pdu executor release locks"); - } - } catch (ASAPException | IOException e) { - // Log.writeLog(this, this.getLogParameter(), "problem when executing asap received pdu: " + e); - this.terminate("problem when executing asap received pdu: ", e); - } - } - } - - // asap session ended - } - - private Thread threadUsingStreams = null; - private synchronized Thread getThreadUsingStreams(Thread t) { - if(this.threadUsingStreams == null) { - this.threadUsingStreams = t; - return null; - } - - return this.threadUsingStreams; - } - - // why not simply synchronized(this) { ... }?? OK, that code works but looks complicated (thsc42) - private void wait4ExclusiveStreamsAccess() { - // synchronize with other thread using streams - Thread threadUsingStreams = this.getThreadUsingStreams(Thread.currentThread()); - - // got lock - go ahead - if(threadUsingStreams == null) { - return; - } - - // there is another thread - wait until it dies - do { - Log.writeLog(this, this.getLogParameter(), "enter waiting loop for exclusive stream access"); - // wait - try { - this.threadWaiting4StreamsLock = Thread.currentThread(); - threadUsingStreams.join(); - } catch (InterruptedException e) { - Log.writeLog(this, this.getLogParameter(), "woke up from join"); - } - finally { - this.threadWaiting4StreamsLock = null; - } - // try again - Log.writeLog(this, this.getLogParameter(), "try to get streams access again"); - threadUsingStreams = this.getThreadUsingStreams(Thread.currentThread()); - } while(threadUsingStreams != null); - Log.writeLog(this, this.getLogParameter(), "leave waiting loop for exclusive stream access"); - } - - private void releaseStreamsLock() { - this.threadUsingStreams = null; // take me out - if(this.threadWaiting4StreamsLock != null) { - Log.writeLog(this, this.getLogParameter(), "wake waiting thread"); - this.threadWaiting4StreamsLock.interrupt(); - } - } - - private void runObservedThread(Thread t, long maxExecutionTime) throws ASAPExecTimeExceededException { - this.managementThread = Thread.currentThread(); - t.start(); - - // wait for reader - try { - Thread.sleep(maxExecutionTime); - } catch (InterruptedException e) { - // was woken up by thread - that's good - return; - } - - StringBuilder sb = new StringBuilder(); - sb.append("thread ("); - sb.append(t.getClass().getSimpleName()); - sb.append(") exceeded max execution time of "); - sb.append(maxExecutionTime); - sb.append(" ms"); - - throw new ASAPExecTimeExceededException(sb.toString()); - } - - private class ASAPPDUExecutor extends Thread { - private final ASAP_PDU_1_0 asapPDU; - private final InputStream is; - private final OutputStream os; - private final EngineSetting engineSetting; - private final ASAP_1_0 protocol; - private final ThreadFinishedListener threadFinishedListener; - private final String encounteredPeer; - private final ASAPEncounterConnectionType connectionType; - - public ASAPPDUExecutor(ASAP_PDU_1_0 asapPDU, String encounteredPeer, InputStream is, OutputStream os, - EngineSetting engineSetting, ASAP_1_0 protocol, - ASAPEncounterConnectionType connectionType, ThreadFinishedListener threadFinishedListener) { - this.asapPDU = asapPDU; - this.encounteredPeer = encounteredPeer; - this.is = is; - this.os = os; - this.engineSetting = engineSetting; - this.protocol = protocol; - this.connectionType = connectionType; - this.threadFinishedListener = threadFinishedListener; - - StringBuilder sb = new StringBuilder(); - sb.append(getLogParameter()); - sb.append("ASAPPDUExecutor: "); - sb.append("engine: " + engineSetting.engine.getClass().getSimpleName() + " | "); - if(engineSetting.listener != null) { - sb.append("listener: " + engineSetting.listener.getClass().getSimpleName() + " | "); - } - sb.append("folder: " + engineSetting.folder); - - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), sb.toString()); - } - - private void finish() { - if(this.threadFinishedListener != null) { - this.threadFinishedListener.finished(this); - } - } - - public void run() { - if(engineSetting.engine == null) { - Log.writeLogErr(this, ASAPSessionImpl.this.getLogParameter(), - "ASAPPDUExecutor called without engine set - fatal"); - this.finish(); - return; - } - - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "ASAPPDUExecutor calls engine: " + engineSetting.engine.getClass().getSimpleName()); - - try { - switch (asapPDU.getCommand()) { - // TODO add encrypt / sign as parameter.. - case ASAP_1_0.INTEREST_CMD: - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "ASAPPDUExecutor call handleASAPInterest"); - engineSetting.engine.handleASAPInterest( - (ASAP_Interest_PDU_1_0) asapPDU, this.protocol, - this.encounteredPeer, - this.os, - this.connectionType); - break; - case ASAP_1_0.ASSIMILATE_CMD: - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "ASAPPDUExecutor call handleASAPAssimilate"); - engineSetting.engine.handleASAPAssimilate( - (ASAP_AssimilationPDU_1_0) this.asapPDU, - this.protocol, - this.encounteredPeer, this.is, this.os, - this.connectionType, - this.engineSetting.listener); - break; - - default: - Log.writeLogErr(this, ASAPSessionImpl.this.getLogParameter(), - "unknown ASAP command: " + asapPDU.getCommand()); - } - } - catch(ASAPException asape) { - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "while processing PDU (go ahead): " + asape.getLocalizedMessage()); - } - catch(IOException ioe) { - Log.writeLogErr(this, ASAPSessionImpl.this.getLogParameter(), - "IOException while processing ASAP PDU - close streams: " + ioe.getLocalizedMessage()); - try { - os.close(); // more important to close than input stream - try first - is.close(); - } catch (IOException ex) { - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), ex.getLocalizedMessage()); - //ex.printStackTrace(); - } - } - finally { - this.finish(); - } - } - } - - /** - * Waits for one PDU and goes away if read. - */ - private class ASAPPDUReader extends Thread { - private final ASAP_1_0 protocol; - private final InputStream is; - private final ThreadFinishedListener pduReaderListener; - private ASAP_PDU_1_0 asapPDU = null; - private IOException ioException = null; - private ASAPException asapException = null; - - ASAPPDUReader(ASAP_1_0 protocol, InputStream is, ThreadFinishedListener listener) { - this.protocol = protocol; - this.is = is; - this.pduReaderListener = listener; - } - - IOException getIoException() { - return this.ioException; - } - - ASAPException getAsapException() { - return this.asapException; - } - - ASAP_PDU_1_0 getASAPPDU() { - return this.asapPDU; - } - - public void run() { - try { - //boolean dropped = false; - //do { - //if(dropped) Log.writeLog(this, "dropped pdu: no sufficient encryption"); - this.asapPDU = protocol.readPDU(is); - //dropped = true; - //} // refuse lesser security settings and read next pdu - //while((encrypt && !this.asapPDU.encrypted()) || (sign && !this.asapPDU.verified())); - } catch (IOException e) { - this.ioException = e; - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "IOException when reading from stream"); - } catch (ASAPException e) { - Log.writeLog(this, ASAPSessionImpl.this.getLogParameter(), - "ASAPException when reading from stream"); - this.asapException = e; - } - finally { - if(this.pduReaderListener != null) { - this.pduReaderListener.finished(this); - } - } - } - } - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(this.asapInternalPeer.getOwner()); - sb.append(" <--> "); - if(this.encounteredPeer == null) sb.append(""); - else sb.append(this.encounteredPeer); - sb.append(" | type: "); - sb.append(this.connectionType); - sb.append(" | encrypted: "); - sb.append(this.encrypt); - sb.append(" | sign: "); - sb.append(this.sign); - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_1_0.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_1_0.java deleted file mode 100644 index 5fc4e86..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_1_0.java +++ /dev/null @@ -1,229 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.crypto.ASAPPoint2PointCryptoSettings; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; -import java.util.Map; - -/** - * Descriptions of ASAP protocol data units and some constants - */ -public interface ASAP_1_0 { - byte DEFAULT_INITIAL_TTL = 6; // a small world is assumed - - int ENCRYPTED_MASK = 0x1; // 0001 - byte ENCRYPTED_CMD = 1; - - int CMD_MASK = 0x6; // 0110 - first bit tells if encrypted or not - byte INTEREST_CMD = 0; - byte ASSIMILATE_CMD = 2; - - String ANY_FORMAT = "ASAP_ANY_FORMAT"; - String ASAP_MANAGEMENT_FORMAT = "asap/control"; - int ERA_NOT_DEFINED = -1; - - /* - OFFER: An peer (optional) in an range of era (optional) offers data for - an channel (optional) in a format (mandatory) - */ - - /** - * @param peer identifies a peer - can be null - * @param era - current era of this peer (range 0..2^8) (-1 indicates: no information about era to be transmitted) - * @param channel describes a channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ -// void offer(CharSequence peer, CharSequence format, CharSequence channel, int era, OutputStream os, boolean signed) -// throws IOException, ASAPException; - - /** - * @param recipient identifies a peer - can be null - * @param channel describes a channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ -// void offer(CharSequence recipient, CharSequence format, CharSequence channel, OutputStream os, boolean signed) -// throws IOException, ASAPException; - - /* - INTEREST: Sender declares an interest for data from a peer (optional) within a range of era (optional) of a - channel (optional) in a format (mandatory) - */ - - /** - * @param sender identifies sender - can be null - * @param recipient can be null - no restriction - any encountered peer will get it. - * @param eraFrom lower limit of era range (-1 means undefined) - * @param eraTo upper limit of era range (-1 means undefined) - * @param channel whished / required channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, boolean signed) throws IOException, ASAPException; - - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, ASAPPoint2PointCryptoSettings cryptoSettings) throws IOException, ASAPException; - - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, ASAPPoint2PointCryptoSettings cryptoSettings, - boolean asapRoutingAllowed) throws IOException, ASAPException; - - /** - * @param sender identifies sender - can be null - * @param recipient can be null - no restriction - any encountered peer will get it. - * @param channel whished / required channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, OutputStream os) throws IOException, ASAPException; - - /** - * @param sender identifies sender - can be null - * @param recipient can be null - no restriction - any encountered peer will get it. - * @param eraFrom lower limit of era range (-1 means undefined) - * @param eraTo upper limit of era range (-1 means undefined) - * @param channel whished / required channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @param sign sign message when sending - * @param encrypted encrypt method - of possible - * @throws IOException - * @throws ASAPException - */ - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, boolean sign, boolean encrypted) - throws IOException, ASAPException, ASAPSecurityException; - - void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, boolean sign, boolean encrypted, - boolean asapRoutingAllowed, Map encounterMap) - throws IOException, ASAPException, ASAPSecurityException; - - /** - * @param sender identifies sender - can be null - * @param channel whished / required channel (can be null) - * @param format describes format - used to describe an application that can deal with transmitted data format. - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void interest(CharSequence sender, CharSequence format, CharSequence sourcePeer, - CharSequence channel, OutputStream os, boolean signed, boolean encrypted) - throws IOException, ASAPException; - - /* - ASSIMILATE: Peer (optional) issues data (mandatory) to a channel (mandatory) in a format (mandatory) of a - era (optional) - */ - - /** - * - * @param sender sender (optional, can be null) - * @param recipient wished recipient (optional, can be null) - * @param channelUri mandatory - * @param format mandatory - * @param offsets applications will probably store a number of messages in a data block. This (optional) list - * of numbers represents the offset where a new app specific message begins. - * @param dataIS stream from which are read to be transmitted to recipient mandatory - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channelUri, int era, - long length, List offsets, List asapHops, InputStream dataIS, OutputStream os, boolean signed) - throws IOException, ASAPException; - - - void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int era, long length, List offsets, List asapHopList, - InputStream dataIS, - OutputStream os, ASAPPoint2PointCryptoSettings secureSetting) throws IOException, ASAPException; - - /** - * - * @param sender sender (optional, can be null) - * @param recipient wished recipient (optional, can be null) - * @param channelUri mandatory - * @param format mandatory - * @param offsets applications will probably store a number of messages in a data block. This (optional) list - * of numbers represents the offset where a new app specific message begins. - * @param dataIS stream from which are read to be transmitted to recipient mandatory - * @param os stream that PDU is to be sent - * @param signed message is signed - * @param encrypted encrypt or not - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channelUri, int era, - long length, List offsets, List asapHops, - InputStream dataIS, OutputStream os, boolean signed, boolean encrypted) - throws IOException, ASAPException; - - /** - * - * @param sender sender (optional, can be null) - * @param recipient wished recipient (optional, can be null) - * @param channel mandatory - * @param format mandatory - * @param offsets applications will probably store a number of messages in a data block. This (optional) list - * of numbers represents the offset where a new app specific message begins. - * @param data which are read to be transmitted to recipient mandatory - * @param os stream that PDU is to be sent - * @param signed message is signed - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channel, int era, - List offsets, List asapHops, byte[] data, OutputStream os, boolean signed) - throws IOException, ASAPException; - - /** - * - * @param sender sender (optional, can be null) - * @param recipient wished recipient (optional, can be null) - * @param channel mandatory - * @param format mandatory - * @param offsets applications will probably store a number of messages in a data block. This (optional) list - * of numbers represents the offset where a new app specific message begins. - * @param data which are read to be transmitted to recipient mandatory - * @param os stream that PDU is to be sent - * @param signed message is signed - * @param encrypted encrypt or not - * @throws IOException exception during writing on stream - * @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, .. - */ - void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channel, int era, - List offsets, List asapHops, byte[] data, OutputStream os, boolean signed, boolean encrypted) - throws IOException, ASAPException; - - - ASAP_PDU_1_0 readPDU(InputStream is) throws IOException, ASAPException; - -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_AssimilationPDU_1_0.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_AssimilationPDU_1_0.java deleted file mode 100644 index cf6fa74..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_AssimilationPDU_1_0.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPHop; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -public interface ASAP_AssimilationPDU_1_0 extends ASAP_PDU_1_0 { - String getRecipientPeer(); - - byte[] getData() throws IOException; - - /** - * @return full length of chunk data, regardless of any internal message - * structure whatsoever. - */ - long getLength(); - - /** - * it is assumed that the stream of bytes contains a number of - * opaque, application specific messages. This list contains the offsets where - * each message starts. The obvious first offset 0 is not part of this - * list. Thus, an empty list means: There is only one application specific - * message in this data block. - * - * Applications don't have to use this feature, e.g. if it tempers with - * encryption / security issues. - * - * @return list of numbers. Each number states the position of the first byte - * of each message. There is no number 0: First message starts - of course - at the beginning. - */ - List getMessageOffsets(); - - List getASAPHopList(); - - /** - * Streams data into a storage. That method should be used instead of getData() when possible. - * Data can directly be passed from network to its final destination without allocation memory - * storage. - * @param os - * @throws IOException - */ - void streamData(OutputStream os) throws IOException; - - /** - * return row input stream from protocol - handle with care! - * @return - */ - public InputStream getInputStream() throws IOException; -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_Interest_PDU_1_0.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_Interest_PDU_1_0.java deleted file mode 100644 index ddc6d4f..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_Interest_PDU_1_0.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.sharksystem.asap.protocol; - -import java.util.Map; - -public interface ASAP_Interest_PDU_1_0 extends ASAP_PDU_1_0 { - boolean eraFromSet(); - boolean eraToSet(); - int getEraFrom(); - int getEraTo(); - Map getEncounterMap(); -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_Modem_Impl.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_Modem_Impl.java deleted file mode 100644 index 8e9131d..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_Modem_Impl.java +++ /dev/null @@ -1,275 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.engine.ASAPUndecryptableMessageHandler; -import net.sharksystem.asap.crypto.ASAPCryptoAlgorithms; -import net.sharksystem.asap.crypto.ASAPKeyStore; -import net.sharksystem.asap.crypto.ASAPPoint2PointCryptoSettings; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.utils.Log; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; -import java.util.Map; - -public class ASAP_Modem_Impl implements ASAP_1_0 { - private final ASAPKeyStore signAndEncryptionKeyStorage; - private final ASAPUndecryptableMessageHandler undecryptableMessageHandler; - private byte initialTTL = DEFAULT_INITIAL_TTL; - - public ASAP_Modem_Impl() { - this(null, null); - } - - public ASAP_Modem_Impl(ASAPUndecryptableMessageHandler undecryptableMessageHandler) { - this(null, undecryptableMessageHandler); - } - - public ASAP_Modem_Impl(ASAPKeyStore signAndEncryptionKeyStorage) { - this(signAndEncryptionKeyStorage, null); - } - - public ASAP_Modem_Impl(ASAPKeyStore signAndEncryptionKeyStorage, - ASAPUndecryptableMessageHandler undecryptableMessageHandler) { - this.signAndEncryptionKeyStorage = signAndEncryptionKeyStorage; - this.undecryptableMessageHandler = undecryptableMessageHandler; - } - - // Character are transmitted as bytes: number of bytes (first byte), content following, 0 mean no content - /* - general structure (asap message) - a) no encryption - CMD | FLAGS | ... specifics - - b) encryption - CMD | algorithm | recipient | encrypted message len | encrypted FLAGS | ... specifics - */ - - /* - @Override - public void offer(CharSequence peer, CharSequence format, CharSequence channel, int era, - OutputStream os, boolean signed) throws IOException, ASAPException { - OfferPDU_Impl.sendPDU(peer, format, channel, era, os, signed); - } - - @Override - public void offer(CharSequence recipient, CharSequence format, CharSequence channel, - OutputStream os, boolean signed) throws IOException, ASAPException { - this.offer(recipient, format, channel, ERA_NOT_DEFINED, os, signed); - } - */ - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, OutputStream os, boolean signed, - boolean encryted) throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, ERA_NOT_DEFINED, ERA_NOT_DEFINED, os, - signed, encryted); - } - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, OutputStream os) throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, os, false, false); - } - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed) - throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, eraFrom, eraTo, os, - signed, false); - } - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, OutputStream os, - ASAPPoint2PointCryptoSettings cryptoSettings) - throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, eraFrom, eraTo, os, - cryptoSettings.mustSign(), cryptoSettings.mustEncrypt()); - } - - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, - OutputStream os, ASAPPoint2PointCryptoSettings cryptoSettings, - boolean asapRoutingAllowed) throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, eraFrom, eraTo, os, - cryptoSettings.mustSign(), cryptoSettings.mustEncrypt(), asapRoutingAllowed, - (Map) null); - - } - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed, - boolean encrypted) throws IOException, ASAPException { - - this.interest(sender, recipient, format, channel, - eraFrom, eraTo, os, signed, encrypted, true, (Map) null); - } - - @Override - public void interest(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed, - boolean encrypted, boolean asapRoutingAllowed, Map encounterMap) - throws IOException, ASAPException { - - // prepare encryption and signing if required - ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(ASAP_1_0.INTEREST_CMD, - os, signed, encrypted, recipient, - this.signAndEncryptionKeyStorage); - - cryptoMessage.sendCmd(); - - InterestPDU_Impl.sendPDUWithoutCmd(sender, recipient, format, channel, eraFrom, eraTo, - cryptoMessage.getOutputStream(), signed, asapRoutingAllowed, encounterMap); - - // finish crypto session - maybe nothing has to be done - cryptoMessage.finish(); - } - - @Override - public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int era, long length, List offsets, List asapHops, - InputStream dataIS, - OutputStream os, boolean signed) throws IOException, ASAPException { - - this.assimilate(sender, recipient, format, channel, era, length, - offsets, asapHops, dataIS, os, signed, false); - } - - @Override - public void assimilate(CharSequence sender, CharSequence receiver, CharSequence format, - CharSequence channel, int era, long length, List offsets, List asapHops, - InputStream dataIS, OutputStream os, - ASAPPoint2PointCryptoSettings secureSetting) - - throws IOException, ASAPException { - - this.assimilate(sender, receiver, format, channel, era, length, offsets, asapHops, dataIS, os, - secureSetting.mustSign(), secureSetting.mustEncrypt()); - } - - /* TODO we need three peers here: both side of the current encounter but also the E2E sender (which is sender here) - the Point2Point sender is not present which makes signing a problem - */ - @Override - public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int era, long length, List offsets, List asapHops, - InputStream dataIS, - OutputStream os, boolean signed, boolean encrypted) throws IOException, ASAPException { - - // prepare encryption and signing if required - ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(ASAP_1_0.ASSIMILATE_CMD, - os, signed, encrypted, recipient, - this.signAndEncryptionKeyStorage); - - cryptoMessage.sendCmd(); - - AssimilationPDU_Impl.sendPDUWithoutCmd(sender, recipient, format, channel, era, - length, offsets, asapHops, dataIS, cryptoMessage.getOutputStream(), signed); - - // finish crypto session - maybe nothing has to be done - cryptoMessage.finish(); - } - - @Override - public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int era, List offsets, List asapHops, byte[] data, - OutputStream os, boolean signed) throws IOException, ASAPException { - - this.assimilate(sender, recipient, format, channel, era, offsets, asapHops, data, os, signed, false); - } - - @Override - public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int era, List offsets, List asapHops, byte[] data, - OutputStream os, boolean signed, boolean encrypted) throws IOException, ASAPException { - - if(data == null || data.length == 0) throw new ASAPException("data must not be null"); - if(era < -1) throw new ASAPException("era must be a non-negative value: " + era); - - this.assimilate(sender, recipient, format, channel, era, data.length, offsets, asapHops, - new ByteArrayInputStream(data), os, signed, encrypted); - } - - @Override - public ASAP_PDU_1_0 readPDU(InputStream is) throws IOException, ASAPException { - byte cmd = ASAPSerialization.readByte(is); - - // encrypted? - boolean encrypted = (cmd & ENCRYPTED_MASK) != 0; - - if(encrypted) { - ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(this.signAndEncryptionKeyStorage); - boolean ownerIsRecipient = cryptoMessage.initDecryption(cmd, is); - if(ownerIsRecipient) { - // peer is recipient - decrypt and go ahead - InputStream decryptedIS = cryptoMessage.doDecryption(); - is = decryptedIS; - } else { - // we cannot decrypt this message - we are not recipient - but we can keep and redistribute it - ASAPCryptoAlgorithms.EncryptedMessagePackage encryptedASAPMessage = cryptoMessage.getEncryptedMessage(); - if(this.undecryptableMessageHandler != null) { - Log.writeLog(this, "cannot decrypt message - call specific handler"); - this.undecryptableMessageHandler.handleUndecryptableMessage( - encryptedASAPMessage, cryptoMessage.getReceiver()); - } else { - Log.writeLog(this, "no handler for undecryptable messages found"); - } - // throw exception anyway - could not create PDU - throw new ASAPSecurityException("unable to decrypt message - most probably not receiver"); - } - } - - int flagsInt = PDU_Impl.readFlags(is); - //ASAPSerialization.readByte(is); - - InputStream realIS = is; - ASAPCryptoMessage verifyCryptoMessage = null; - if(PDU_Impl.flagSet(PDU_Impl.SIGNED_TO_BIT_POSITION, flagsInt)) { - verifyCryptoMessage = new ASAPCryptoMessage(this.signAndEncryptionKeyStorage); - is = verifyCryptoMessage.setupCopyInputStream(flagsInt, is); - } - - PDU_Impl pdu = null; - - // remove encrypted flag - cmd = (byte)(cmd & CMD_MASK); - switch(cmd) { - case ASAP_1_0.INTEREST_CMD: pdu = new InterestPDU_Impl(flagsInt, encrypted, is); break; - case ASAP_1_0.ASSIMILATE_CMD: pdu = new AssimilationPDU_Impl(flagsInt, encrypted, is); break; - default: throw new ASAPException("unknown command: " + cmd); - } - - if(verifyCryptoMessage != null) { - String sender = pdu.getSender(); - if(sender != null) { - // read signature and try to verify - try { - pdu.setVerified(verifyCryptoMessage.verify(sender, realIS)); - } - catch(ASAPException e) { - Log.writeLog(this, " cannot verify message"); - } - } - } - - return pdu; - } - - private String getLogStart() { - return this.getClass().getSimpleName() + ": "; - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_OfferPDU_1_0.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_OfferPDU_1_0.java deleted file mode 100644 index f835349..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_OfferPDU_1_0.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.sharksystem.asap.protocol; - -public interface ASAP_OfferPDU_1_0 extends ASAP_PDU_1_0 { -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_1_0.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_1_0.java deleted file mode 100644 index 7f346fc..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_1_0.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.sharksystem.asap.protocol; - -public interface ASAP_PDU_1_0 { - /** - * @return ASAP command. Version 1 know three alternatives: interest, offer, assimilate - */ - byte getCommand(); - - /** - * @return ID of sender of this message - optional - */ - String getSender(); - - /** - * @return ID of recipient of this message - optional - */ - String getRecipient(); - - /** - * @return format A URI style is strongly recommended. - * In most cases a format will match with an application that deals with one (or more - * formats) - * - */ - String getFormat(); - - /** - * @return A URI representing content (semantics) of this message. - * It is assumed that multiple messages with same uri are floating around the - * ASAP network - */ - String getChannelUri(); - - /** - * @return Sender can send era in which this message was created. Can be helpful - * in multihop networks to reduce communication costs. - */ - int getEra(); - - /** - * @return a flag that indicates whether the optional sender parameter was transmitted - */ - boolean senderSet(); - - /** - * @return true if received message was encrypted and could obviously be encrypted - */ - boolean encrypted(); - - /** - * @return true if received message was signed - */ - boolean signed(); - - /** - * @return true if received message was signed and signature could be verified - */ - boolean verified(); - - /** - * @return a flag that indicates whether the optional recipient parameter was transmitted - */ - boolean recipientSet(); - /** - * @return a flag that indicates whether the optional channel parameter was transmitted - */ - boolean channelSet(); - /** - * @return a flag that indicates whether the optional era parameter was transmitted - */ - boolean eraSet(); - - /** - * Routing allowed - yes or no - * @return - */ - public boolean routing(); - - /** - * Sent an encounter list? - * @return - */ - public boolean encounterList(); - - /** - * Make sure that their are no more data on the real input stream. This pdu object will no longer be used. - */ - void takeDataFromStream(); -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_Management.java b/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_Management.java deleted file mode 100644 index 6b40fef..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ASAP_PDU_Management.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.sharksystem.asap.protocol; - -interface ASAP_PDU_Management { - void setVerified(boolean b); -} diff --git a/src/main/java/net/sharksystem/asap/protocol/AssimilationPDU_Impl.java b/src/main/java/net/sharksystem/asap/protocol/AssimilationPDU_Impl.java deleted file mode 100644 index 3b004ee..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/AssimilationPDU_Impl.java +++ /dev/null @@ -1,211 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -class AssimilationPDU_Impl extends PDU_Impl implements ASAP_AssimilationPDU_1_0 { - private final long dataLength; - private final InputStream is; - private String recipientPeer; - public static final String OFFSET_DELIMITER = ","; - private List offsets = new ArrayList<>(); - - private byte[] data = null; - private boolean dataNoLongerOnStream = false; - private List asapHopList; - - // PDU: CMD | FLAGS | PEER | RECIPIENT | FORMAT | CHANNEL | ERA | OFFSETS | LENGTH | DATA - - public AssimilationPDU_Impl(int flagsInt, boolean encrypted, InputStream is) throws IOException, ASAPException { - super(ASAP_1_0.ASSIMILATE_CMD, encrypted); - - evaluateFlags(flagsInt); - - if(this.senderSet()) { this.readSender(is); } - if(this.recipientSet()) { this.readRecipientPeer(is); } - this.readFormat(is); - if(this.channelSet()) { this.readChannel(is); } - if(this.eraSet()) { this.readEra(is); } - if(this.offsetsSet()) { this.readOffsets(is); } - this.readASAPHops(is); - - this.dataLength = ASAPSerialization.readLongParameter(is); - - this.is = is; - - if(this.signed()) { - // read data from stream, verification needs to reach signature - this.getData(); - } - } - - private void readOffsets(InputStream is) throws IOException, ASAPException { - this.offsets = string2list(ASAPSerialization.readCharSequenceParameter(is)); - } - - private void readASAPHops(InputStream is) throws IOException, ASAPException { - this.asapHopList = ASAPSerialization.readASAPHopList(is); - } - - private void readRecipientPeer(InputStream is) throws IOException, ASAPException { - this.recipientPeer = ASAPSerialization.readCharSequenceParameter(is); - } - - static void sendPDUWithoutCmd(CharSequence peer, CharSequence recipient, CharSequence format, CharSequence channel, - int era, long length, List offsets, List asapHops, InputStream is, OutputStream os, - boolean signed) - throws IOException, ASAPException { - - // first: check protocol errors - PDU_Impl.checkValidEra(era); - PDU_Impl.checkValidFormat(format); - PDU_Impl.checkValidStream(os); - - // create parameter bytes - int flags = 0; - flags = PDU_Impl.setFlag(peer, flags, SENDER_BIT_POSITION); - flags = PDU_Impl.setFlag(recipient, flags, RECIPIENT_BIT_POSITION); - flags = PDU_Impl.setFlag(channel, flags, CHANNEL_BIT_POSITION); - flags = PDU_Impl.setFlag(era, flags, ERA_BIT_POSITION); - flags = PDU_Impl.setFlag(offsets, flags, OFFSETS_BIT_POSITION); - flags = PDU_Impl.setFlag(signed, flags, SIGNED_TO_BIT_POSITION); - - PDU_Impl.sendFlags(flags, os); - - ASAPSerialization.writeCharSequenceParameter(peer, os); // opt - ASAPSerialization.writeCharSequenceParameter(recipient, os); // opt - ASAPSerialization.writeCharSequenceParameter(format, os); // mand - ASAPSerialization.writeCharSequenceParameter(channel, os); // opt - ASAPSerialization.writeNonNegativeIntegerParameter(era, os); // opt - ASAPSerialization.writeCharSequenceParameter(list2string(offsets), os); // opt - ASAPSerialization.writeASAPHopList(asapHops, os); // mand - can be null (length == 0) - ASAPSerialization.writeLongParameter(length, os); // mand - - // stream data - while(length-- > 0) { - os.write(is.read()); - } - } - - static String list2string(List list) { - if(list == null || list.size() == 0) return null; - - StringBuilder sb = new StringBuilder(); - - boolean first = true; - for(Long i : list) { - if(!first) { - sb.append(OFFSET_DELIMITER); - } - else first = false; - - sb.append(i); - } - - return sb.toString(); - } - - private List string2list(String s) throws ASAPException { - List l = new ArrayList<>(); - - StringTokenizer st = new StringTokenizer(s, OFFSET_DELIMITER); - - try { - while (st.hasMoreTokens()) { - l.add(Integer.parseInt(st.nextToken())); - } - } - catch(RuntimeException re) { - throw new ASAPException("malformed offset parameter in received data: " + s); - } - - return l; - - } - - @Override - public String getRecipientPeer() { return this.recipientPeer; } - - @Override - public long getLength() { return this.dataLength; } - - @Override - public List getMessageOffsets() { - return this.offsets; - } - - public List getASAPHopList() { - return this.asapHopList; - } - - @Override - public byte[] getData() throws IOException { - if(this.data == null) { - if(this.dataNoLongerOnStream) - throw new IOException(this.getLogStart() + "data are already read from stream, probably with streamData"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - this.streamData(baos); - this.data = baos.toByteArray(); - } - - return this.data; - } - - private String getLogStart() { - return this.getClass().getSimpleName() + ": "; - } - - public InputStream getInputStream() throws IOException { - if(this.dataNoLongerOnStream) { - if(this.data == null) { - throw new IOException(this.getLogStart() - + "data are no longer in stream, probably due to a previous call of streamData or getInputStream"); - } else { - return new ByteArrayInputStream(this.data); - } - } - - this.dataNoLongerOnStream = true; // educated guess - they will be gone very soon. - return this.is; - } - - @Override - public void takeDataFromStream() { - // read data from stream - most probably to drop this pdu - try { - this.getData(); - } catch (IOException e) { - // ok - in any case - data is taken away from stream - } - } - - @Override - public void streamData(OutputStream os) throws IOException { - InputStream useIS; - - if(this.data == null) { - if(this.dataNoLongerOnStream) { - throw new IOException(this.getLogStart() - + "data are already read from stream, probably previous call of streamData"); - } else { - // data are still on stream - useIS = this.is; - // but not any longer - this.dataNoLongerOnStream = true; - } - } else { - // already read - useIS = new ByteArrayInputStream(this.data); - } - - for (int i = 0; i < this.dataLength; i++) { - os.write(useIS.read()); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/InterestPDU_Impl.java b/src/main/java/net/sharksystem/asap/protocol/InterestPDU_Impl.java deleted file mode 100644 index 726245a..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/InterestPDU_Impl.java +++ /dev/null @@ -1,121 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -class InterestPDU_Impl extends PDU_Impl implements ASAP_Interest_PDU_1_0 { - private int eraFrom; - private int eraTo; - private Map encounterMap; - - InterestPDU_Impl(int flagsInt, boolean encrypted, InputStream is) throws IOException, ASAPException { - super(ASAP_1_0.INTEREST_CMD, encrypted); - - evaluateFlags(flagsInt); - - if(this.senderSet()) { this.readSender(is); } - if(this.recipientSet()) { this.readRecipient(is); } - this.readFormat(is); // mandatory - if(this.channelSet()) { this.readChannel(is); } - if(this.eraFromSet()) { this.readFromEra(is); } - if(this.eraToSet()) { this.readToEra(is); } - - if(this.encounterList()) { - this.encounterMap = this.readEncounterMap(is); - } - } - - public Map getEncounterMap() { - return this.encounterMap; - } - - private void readToEra(InputStream is) throws IOException, ASAPException { - this.eraTo = ASAPSerialization.readIntegerParameter(is); - } - - private void readFromEra(InputStream is) throws IOException, ASAPException { - this.eraFrom = ASAPSerialization.readIntegerParameter(is); - } - - static void sendPDUWithoutCmd(CharSequence sender, CharSequence recipient, CharSequence format, - CharSequence channel, int eraFrom, int eraTo, OutputStream os, - boolean signed, boolean routingAllowed, Map encounterMap) - throws IOException, ASAPException { - - if(format == null || format.length() < 1) format = ASAP_1_0.ANY_FORMAT; - - // first: check protocol errors - PDU_Impl.checkValidEra(eraFrom); - PDU_Impl.checkValidEra(eraTo); - PDU_Impl.checkValidFormat(format); - PDU_Impl.checkValidStream(os); - - // create parameter bytes - int flags = 0; - flags = PDU_Impl.setFlag(sender, flags, SENDER_BIT_POSITION); - flags = PDU_Impl.setFlag(recipient, flags, RECIPIENT_BIT_POSITION); - flags = PDU_Impl.setFlag(channel, flags, CHANNEL_BIT_POSITION); - flags = PDU_Impl.setFlag(eraFrom, flags, ERA_FROM_BIT_POSITION); - flags = PDU_Impl.setFlag(eraTo, flags, ERA_TO_BIT_POSITION); - - // just flags, no additional data - flags = PDU_Impl.setFlag(signed, flags, SIGNED_TO_BIT_POSITION); - flags = PDU_Impl.setFlag(routingAllowed, flags, ROUTING_BIT_POSITION); - - flags = PDU_Impl.setFlag(encounterMap != null && !encounterMap.isEmpty(), - flags, ENCOUNTER_MAP_BIT_POSITION); - - // send flags - PDU_Impl.sendFlags(flags, os); - - // send data - ASAPSerialization.writeCharSequenceParameter(sender, os); // opt - ASAPSerialization.writeCharSequenceParameter(recipient, os); // opt - ASAPSerialization.writeCharSequenceParameter(format, os); // mand - ASAPSerialization.writeCharSequenceParameter(channel, os); // opt - ASAPSerialization.writeNonNegativeIntegerParameter(eraFrom, os); // opt - ASAPSerialization.writeNonNegativeIntegerParameter(eraTo, os); // opt - - if(encounterMap != null && !encounterMap.isEmpty()) { - // serialize encounter map - - // write size - ASAPSerialization.writeNonNegativeIntegerParameter(encounterMap.size(), os); - - for(String peerID : encounterMap.keySet()) { - ASAPSerialization.writeCharSequenceParameter(peerID, os); - ASAPSerialization.writeNonNegativeIntegerParameter(encounterMap.get(peerID), os); - } - } - } - - private Map readEncounterMap(InputStream is) throws IOException, ASAPException { - Map map = new HashMap<>(); - - // read length - int len = ASAPSerialization.readIntegerParameter(is); - for(int i = 0; i < len; i++) { - String peerID = ASAPSerialization.readCharSequenceParameter(is); - int era = ASAPSerialization.readIntegerParameter(is); - map.put(peerID, era); - } - return map; - } - - @Override - public int getEraFrom() { return this.eraFrom; } - - @Override - public int getEraTo() { return this.eraTo; } - - @Override - public void takeDataFromStream() { - // there is nothing to do here - all data are already read when object was created - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/PDU_Impl.java b/src/main/java/net/sharksystem/asap/protocol/PDU_Impl.java deleted file mode 100644 index 85f2a87..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/PDU_Impl.java +++ /dev/null @@ -1,268 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -import static net.sharksystem.asap.protocol.ASAP_1_0.ERA_NOT_DEFINED; - -abstract class PDU_Impl implements ASAP_PDU_1_0, ASAP_PDU_Management { - public static final int SENDER_BIT_POSITION = 0; - public static final int RECIPIENT_BIT_POSITION = 1; - public static final int CHANNEL_BIT_POSITION = 2; - public static final int ERA_BIT_POSITION = 3; - public static final int ERA_FROM_BIT_POSITION = 4; - public static final int ERA_TO_BIT_POSITION = 5; - public static final int OFFSETS_BIT_POSITION = 6; - public static final int SIGNED_TO_BIT_POSITION = 7; - public static final int ROUTING_BIT_POSITION = 8; - public static final int ENCOUNTER_MAP_BIT_POSITION = 9; - - private boolean senderSet = false; - private boolean recipientSet = false; - private boolean channelSet = false; - private boolean eraSet = false; - private boolean eraFrom = false; - private boolean eraTo = false; - private boolean offsetsSet = false; - private boolean routing = false; - private boolean encounterList = false; - - private final byte cmd; - private final boolean encrypted; - - private boolean signed = false; - private boolean verified = false; - - private String sender; - private String recipient; - private String format; - private String channel; - private int era; - - PDU_Impl(byte cmd, boolean encrypted) { - this.cmd = cmd; - this.encrypted = encrypted; - } - - public boolean encrypted() { return this.encrypted; } - public boolean signed() { return this.signed; } - public boolean verified() { return this.verified; }; - public boolean routing() { return this.routing; }; - public boolean encounterList() { return this.encounterList; }; - - public void setVerified(boolean verified) { - this.verified = verified; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("cmd: "); - switch(cmd) { - case ASAP_1_0.INTEREST_CMD: sb.append("I"); break; - case ASAP_1_0.ASSIMILATE_CMD: sb.append("A"); break; - } - sb.append(" | sender: "); if(senderSet) sb.append(this.sender); else sb.append("not set"); - sb.append(" | format: "); sb.append(format); - sb.append(" | channel: "); if(channelSet) sb.append(this.channel); else sb.append("not set"); - sb.append(" | era: "); if(eraSet) sb.append(era); else sb.append("not set"); - sb.append(" | signed: "); this.appendTrueFalse(this.signed, sb); - sb.append(" | verified: "); this.appendTrueFalse(this.verified, sb); - sb.append(" | encrypted: "); this.appendTrueFalse(this.encrypted, sb); - sb.append(" | routing: "); this.appendTrueFalse(this.routing, sb); - sb.append(" | encounterList: "); this.appendTrueFalse(this.encounterList, sb); - - return sb.toString(); - } - - private void appendTrueFalse(boolean value, StringBuilder sb) { - if(value) sb.append("true"); - else sb.append("false"); - } - - /** - * @param cmd - * @param flags - * @param os - * @throws IOException - * @deprecated - */ - protected static void sendHeader(byte cmd, int flags, OutputStream os) throws IOException { - ASAPSerialization.writeByteParameter(cmd, os); // mand - ASAPSerialization.writeByteParameter((byte)flags, os); // mand - } - - public static void sendFlags(int flags, OutputStream os) throws IOException { - // we need two bytes - sent least signification byte first - byte flagBytes = ASAPSerialization.getByteFromInt(flags, 0); - ASAPSerialization.writeByteParameter(flagBytes, os); // mand - flagBytes = ASAPSerialization.getByteFromInt(flags, 1); - ASAPSerialization.writeByteParameter(flagBytes, os); // mand - } - - public static int readFlags(InputStream is) throws IOException, ASAPException { - byte byteLeastSignificant = ASAPSerialization.readByte(is); - byte byteNextByte = ASAPSerialization.readByte(is); - - int flags = byteNextByte; - flags = flags << 8; - // set all random bits to 0 - flags = flags & 0x0000FF00; - - int leastSignificantInt = byteLeastSignificant; - // set all random bits to 0 - leastSignificantInt = leastSignificantInt & 0x000000FF; - - // merge - flags = flags | leastSignificantInt; - - return flags; - } - - public static void sendCmd(byte cmd, OutputStream os) throws IOException { - ASAPSerialization.writeByteParameter(cmd, os); // mand - } - - protected void evaluateFlags(int flag) { - this.senderSet = flagSet(SENDER_BIT_POSITION, flag); - this.recipientSet = flagSet(RECIPIENT_BIT_POSITION, flag); - this.channelSet = flagSet(CHANNEL_BIT_POSITION, flag); - this.eraSet = flagSet(ERA_BIT_POSITION, flag); - this.eraFrom = flagSet(ERA_FROM_BIT_POSITION, flag); - this.eraTo = flagSet(ERA_TO_BIT_POSITION, flag); - this.offsetsSet = flagSet(OFFSETS_BIT_POSITION, flag); - this.signed = flagSet(SIGNED_TO_BIT_POSITION, flag); - this.routing = flagSet(ROUTING_BIT_POSITION, flag); - this.encounterList = flagSet(ENCOUNTER_MAP_BIT_POSITION, flag); - } - - static boolean flagSet(int bitPosition, int flags) { - int flagMask = 1; - flagMask = flagMask << bitPosition; - return (flags & flagMask) != 0; - } - - @Override - public boolean senderSet() { return this.senderSet; } - - @Override - public boolean channelSet() { return this.channelSet; } - - @Override - public boolean eraSet() { return this.eraSet; } - - public boolean eraFromSet() { return this.eraFrom; } - - public boolean eraToSet() { return this.eraTo; } - - public boolean recipientSet() { return this.recipientSet; } - - public boolean offsetsSet() { return this.offsetsSet; } - - @Override - public String getSender() { return this.sender; } - - @Override - public String getRecipient() { return this.recipient; } - - @Override - public String getFormat() { return this.format; } - - @Override - public String getChannelUri() { return this.channel; } - - @Override - public int getEra() { return this.era;} - - - @Override - public byte getCommand() { return this.cmd; } - - protected void readSender(InputStream is) throws IOException, ASAPException { - this.sender = ASAPSerialization.readCharSequenceParameter(is); - } - - protected void readRecipient(InputStream is) throws IOException, ASAPException { - this.recipient = ASAPSerialization.readCharSequenceParameter(is); - } - - protected void readFormat(InputStream is) throws IOException, ASAPException { - this.format = ASAPSerialization.readCharSequenceParameter(is); - } - - - protected void readChannel(InputStream is) throws IOException, ASAPException { - this.channel = ASAPSerialization.readCharSequenceParameter(is); - } - - protected void readEra(InputStream is) throws IOException, ASAPException { - this.era = ASAPSerialization.readIntegerParameter(is); - } - - static void sendCommand(byte cmd, OutputStream os) throws IOException { - os.write(cmd); - } - - /** - * Set flag of parameter is set and will be transmitted - * @param flags - * @param parameter - * @param bit_position - * @return - */ - static int setFlag(CharSequence parameter, int flags, int bit_position) { - if(parameter != null && parameter.length() > 0) { - return setFlag(1, flags, bit_position); - } - return flags; - } - - static int setFlag(List parameter, int flags, int bit_position) { - if(parameter != null && parameter.size() > 0) { - return setFlag(1, flags, bit_position); - } - return flags; - } - - static int setFlag(int parameter, int flags, int bit_position) { - if(parameter != ERA_NOT_DEFINED) { - int newFlag = 1; - newFlag = newFlag << bit_position; - - return flags | newFlag; - } - - return flags; - } - - static int setFlag(boolean parameter, int flags, int bit_position) { - if(parameter) { - int newFlag = 1; - newFlag = newFlag << bit_position; - - return flags | newFlag; - } - - return flags; - } - - static void checkValidStream(OutputStream os) throws ASAPException { - if(os == null) throw new ASAPException("outputstream must not be null"); - } - - static void checkValidFormat(CharSequence format) throws ASAPException { - if(format == null) throw new ASAPException("format must not be null"); - } - - static void checkValidEra(int era) throws ASAPException { - if(era < -1) throw new ASAPException("era cannot be smaller than -1"); - int maxEra = Integer.MAX_VALUE; - // that's impossible but ... never change a running system... - if(era > maxEra) throw new ASAPException("era exceeded max limit of " + Integer.MAX_VALUE); - } -} diff --git a/src/main/java/net/sharksystem/asap/protocol/ThreadFinishedListener.java b/src/main/java/net/sharksystem/asap/protocol/ThreadFinishedListener.java deleted file mode 100644 index c4d07ee..0000000 --- a/src/main/java/net/sharksystem/asap/protocol/ThreadFinishedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.sharksystem.asap.protocol; - -public interface ThreadFinishedListener { - void finished(Thread t); -} diff --git a/src/main/java/net/sharksystem/asap/utils/ASAPChunkReceivedTester.java b/src/main/java/net/sharksystem/asap/utils/ASAPChunkReceivedTester.java deleted file mode 100644 index 71b7b96..0000000 --- a/src/main/java/net/sharksystem/asap/utils/ASAPChunkReceivedTester.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.engine.ASAPChunkAssimilatedListener; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * - * @author thsc - */ -public class ASAPChunkReceivedTester implements ASAPChunkAssimilatedListener { - private CharSequence senderE2E = null; - private CharSequence uri = null; - private int era; - private CharSequence format; - - @Override - public void chunkStored(String format, String senderE2E, String uri, int era, - List asapHop) throws IOException { - - this.chunkAssimilated(format, senderE2E, uri, era, asapHop); - } - - @Override - public void transientMessagesReceived(ASAPMessages transientMessages, ASAPHop asapHop) throws IOException { - List asapHops = new ArrayList<>(); - asapHops.add(asapHop); - this.chunkAssimilated(transientMessages.getFormat(), asapHop.sender(), - transientMessages.getURI(), ASAP.TRANSIENT_ERA, asapHops); - } - - private void chunkAssimilated(CharSequence format, CharSequence senderE2E, CharSequence uri, int era, List asapHop) { - Log.writeLog(this, "chunk assimilated called: (format|sender|uri|era) " + - format + - " | " + - senderE2E + - " | " + - uri + - " | " + - era); - this.format = format; - this.senderE2E = senderE2E; - this.uri = uri; - this.era = era; - - } - - public boolean chunkReceived() { - return this.senderE2E != null; - } - - public String getSenderE2E() { - return this.senderE2E.toString(); - } - - public String getFormat() { - return this.format.toString(); - } - - public String getUri() { - return this.uri.toString(); - } - - public int getEra() { - return this.era; - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/ASAPLogHelper.java b/src/main/java/net/sharksystem/asap/utils/ASAPLogHelper.java deleted file mode 100644 index fafae29..0000000 --- a/src/main/java/net/sharksystem/asap/utils/ASAPLogHelper.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.utils.Log; -import net.sharksystem.utils.Utils; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.engine.ASAPEngine; -import net.sharksystem.asap.engine.ASAPEngineFS; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPMessages; - -import java.io.*; - -public class ASAPLogHelper { - public static final String SERIALIZATION_DELIMITER = "|||"; - - public static ASAPMessages getMessagesByChunkReceivedInfos(String format, String sender, String uri, - String folderName, int era) { - try { - String rootIncomingStorage = folderName + "/" + Utils.url2FileName(format); - Log.writeLog(ASAPLogHelper.class, "try getting storage in folder " + rootIncomingStorage); - ASAPEngine existingASAPEngineFS = - ASAPEngineFS.getExistingASAPEngineFS(rootIncomingStorage); - Log.writeLog(ASAPLogHelper.class, "got existing asap engine"); - - ASAPChunkStorage chunkStorage = existingASAPEngineFS.getReceivedChunksStorage(sender); - Log.writeLog(ASAPLogHelper.class, "got incoming channel of " + sender); - - ASAPMessages asapMessages = chunkStorage.getASAPMessages(uri, era, era); - Log.writeLog(ASAPLogHelper.class, "got messages uri: " + uri + " / era: " + era); - - return asapMessages; - } catch (IOException | ASAPException e) { - Log.writeLog(ASAPLogHelper.class, "could not access message after be informed about new chunk arrival" - + e.getLocalizedMessage()); - } - - return null; - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/ASAPMessages2StringCollectionWrapper.java b/src/main/java/net/sharksystem/asap/utils/ASAPMessages2StringCollectionWrapper.java deleted file mode 100644 index 9f5976a..0000000 --- a/src/main/java/net/sharksystem/asap/utils/ASAPMessages2StringCollectionWrapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.asap.ASAPMessages; - -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -/** - * Assumed ASAPMessages only contain a string - instantiate an object of this class - * with ASAPMessages and get a String iterator - */ -public class ASAPMessages2StringCollectionWrapper implements Iterator { - private final ASAPMessages asapMessages; - private final Iterator byteContentInterator; - - public ASAPMessages2StringCollectionWrapper(ASAPMessages asapMessages) throws IOException { - this.asapMessages = asapMessages; - this.byteContentInterator = this.asapMessages.getMessages(); - } - - @Override - public boolean hasNext() { - return this.byteContentInterator.hasNext(); - } - - @Override - public String next() { - return new String(this.byteContentInterator.next()); - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/ASAPPeerHandleConnectionThread.java b/src/main/java/net/sharksystem/asap/utils/ASAPPeerHandleConnectionThread.java deleted file mode 100644 index fc646cf..0000000 --- a/src/main/java/net/sharksystem/asap/utils/ASAPPeerHandleConnectionThread.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sharksystem.asap.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import net.sharksystem.asap.ASAPConnectionHandler; -import net.sharksystem.asap.ASAPException; - -/** - * - * @author thsc - */ -public class ASAPPeerHandleConnectionThread extends Thread { - private final ASAPConnectionHandler engine; - private final InputStream is; - private final OutputStream os; - - public ASAPPeerHandleConnectionThread(ASAPConnectionHandler engine, InputStream is, OutputStream os) { - this.engine = engine; - this.is = is; - this.os = os; - } - - @Override - public void run() { - try { - this.engine.handleConnection(this.is, this.os); - } catch (IOException | ASAPException e) { - System.err.println(this.getClass().getSimpleName() + ": " + e.getClass().getSimpleName() - + "caught: " + e.getLocalizedMessage()); - } - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/ASAPSerialization.java b/src/main/java/net/sharksystem/asap/utils/ASAPSerialization.java deleted file mode 100644 index 76c95de..0000000 --- a/src/main/java/net/sharksystem/asap/utils/ASAPSerialization.java +++ /dev/null @@ -1,442 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.asap.*; -import net.sharksystem.utils.Log; - -import java.io.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class ASAPSerialization { - public static final long BLANK_LEFT_LONG = 0x00000000FFFFFFFFL; - public static final long BLANK_RIGHT_LONG = 0xFFFFFFFF00000000L; - public static final int BLANK_LEFT_INTEGER = 0x0000FFFF; - public static final int BLANK_RIGHT_INTEGER = 0xFFFF0000; - public static final short BLANK_LEFT_SHORT = 0x00FF; - public static final short BLANK_RIGHT_SHORT = (short) 0xFF00; - - public static String byteArray2String(byte[] serializedString) throws IOException, ASAPException { - ByteArrayInputStream bais = new ByteArrayInputStream(serializedString); - return readCharSequenceParameter(bais); - } - - public static byte[] string2byteArray(CharSequence charSequence2Serialize) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeCharSequenceParameter(charSequence2Serialize, baos); - return baos.toByteArray(); - } - - public static void writeByteArray(byte[] bytes2Write, OutputStream os) throws IOException { - if (bytes2Write == null) { - writeNonNegativeIntegerParameter(0, os); - } else { - writeNonNegativeIntegerParameter(bytes2Write.length, os); - os.write(bytes2Write); - } - } - - public static byte[] readByteArray(InputStream is) throws IOException, ASAPException { - // read len - int len = readIntegerParameter(is); - if (len == 0) return new byte[0]; - - byte[] messageBytes = new byte[len]; - // read encrypted bytes from stream - is.read(messageBytes); - - return messageBytes; - } - - public static void writeByteArray(byte[][] bytes2Dim, OutputStream os) throws IOException { - if (bytes2Dim == null) { - writeNonNegativeIntegerParameter(0, os); - } else { - writeNonNegativeIntegerParameter(bytes2Dim.length, os); - for (int i = 0; i < bytes2Dim.length; i++) { - ASAPSerialization.writeByteArray(bytes2Dim[i], os); - } - } - } - - public static byte[][] readByte2DimArray(InputStream is) throws IOException, ASAPException { - // read len - int len = readIntegerParameter(is); - if (len == 0) return new byte[0][]; - - byte[][] messageBytes = new byte[len][]; - for (int i = 0; i < len; i++) { - messageBytes[i] = ASAPSerialization.readByteArray(is); - } - - return messageBytes; - } - - public static void writeCharSequenceParameter(CharSequence parameter, OutputStream os) throws IOException { - if (parameter == null || parameter.length() < 1) return; //parameter = ""; - byte[] bytes = parameter.toString().getBytes(); - writeNonNegativeIntegerParameter(bytes.length, os); - os.write(bytes); - } - - public static void writeByteParameter(byte parameter, OutputStream os) throws IOException { - os.write(new byte[]{parameter}); - } - - /** - * Return a byte from an int - position starts with 0 at least significant bit - * - * @param source - * @param position - * @return - */ - public static byte getByteFromInt(int source, int position) { - int bitCountShift = position * 8; // byte has got 8 bit - int tmpInt = source >> bitCountShift; - return (byte) (tmpInt); - } - - public static void writeShortParameter(short shortValue, OutputStream os) throws IOException { - // short = 16 bit = 2 bytes - short left = (short) (shortValue & BLANK_RIGHT_SHORT); - left = (short) (left >> 8); - short right = (short) (shortValue & BLANK_LEFT_SHORT); - writeByteParameter((byte) left, os); - // cut left part - writeByteParameter((byte) right, os); - } - - public static void writeNonNegativeIntegerParameter(int parameter, OutputStream os) throws IOException { - if (parameter < 0) return; // non negative! - - // Integer == 32 bit == 4 Byte - int left = parameter >> 16; - writeShortParameter((short) left, os); - writeShortParameter((short) parameter, os); - } - - public static void writeIntegerParameter(int intValue, OutputStream os) throws IOException { - // Integer == 32 bit == 4 Byte - int left = intValue & BLANK_RIGHT_INTEGER; - left = left >> 16; - int right = intValue & BLANK_LEFT_INTEGER; - writeShortParameter((short) left, os); - writeShortParameter((short) right, os); - } - - public static void writeNonNegativeLongParameter(long longValue, OutputStream os) throws IOException { - if (longValue > -1) writeLongParameter(longValue, os); - else throw new IOException("negative value"); - } - - public static void writeLongParameter(long longValue, OutputStream os) throws IOException { - // Long = 64 bit = 2 Integer - long left = longValue & BLANK_RIGHT_LONG; - left = left >> 32; - long right = longValue & BLANK_LEFT_LONG; - writeIntegerParameter((int) left, os); - writeIntegerParameter((int) right, os); - } - - public static void printBits(long l, int bits) { - long mask = 1; - mask = mask << bits - 1; - short byteBitCounter = 4; - StringBuffer stringBuffer = new StringBuffer(); - while (mask != 0) { - if ((l & mask) != 0) stringBuffer.append("1"); - else stringBuffer.append("0"); - if (--byteBitCounter == 0) { - byteBitCounter = 4; - stringBuffer.append(" "); - } - mask = mask >> 1; - } - Log.writeLog(ASAPSerialization.class, stringBuffer.toString() + " "); - } - - public static String printBitsToString(long l, int bits) { - StringBuilder sb = new StringBuilder(); - - long mask = 1; - mask = mask << bits - 1; - short byteBitCounter = 4; - while (mask != 0) { - if ((l & mask) != 0) sb.append("1"); - else sb.append("0"); - if (--byteBitCounter == 0) { - byteBitCounter = 4; - sb.append(" "); - } - mask = mask >> 1; - } - sb.append(" "); - - return sb.toString(); - } - - public static String printByteArrayToString(byte[] byteArray) { - StringBuilder sb = new StringBuilder(); - for (int index = byteArray.length - 1; index >= 0; index--) { - sb.append("["); - sb.append(index); - sb.append("]: "); - sb.append(printByteToString(byteArray[index])); - } - return sb.toString(); - } - - public static String printByteToString(short s) { - return printBitsToString(s, 8); - } - - public static String printBitsToString(int i) { - return printBitsToString(i, 16); - } - - public static void printByteArray(byte[] byteArray) { - for (int index = byteArray.length - 1; index >= 0; index--) { - printByte(byteArray[index]); - } - } - - public static void printByte(short s) { - printBits(s, 8); - } - - public static void printBits(short s) { - printBits(s, 16); - } - - public static void printBits(int i) { - printBits(i, 32); - } - - public static void printBits(long l) { - long left = l & BLANK_RIGHT_LONG; - left = left >> 32; - printBits((int) left); - long right = l & BLANK_LEFT_LONG; - printBits((int) right); - } - - public static byte readByteParameter(InputStream is) throws IOException, ASAPException { - return readByte(is); - } - - public static byte readByte(InputStream is) throws IOException, ASAPException { - try { - int value = is.read(); - if (value < 0) { - throw new ASAPException("read -1: no more data in stream"); - } - return (byte) value; - } catch (IOException e) { - Log.writeLog(ASAPSerialization.class, "caught IOException during readByte(): " - + e.getClass().getSimpleName() + ": " - + e.getLocalizedMessage()); - throw e; - } - } - - public static short readShortParameter(InputStream is) throws IOException, ASAPException { - int value = readByteParameter(is); - value = value << 8; - // be sure - value = value & BLANK_RIGHT_SHORT; - int right = readByteParameter(is); - // be sure - right = right & BLANK_LEFT_SHORT; - value += right; - - return (short) value; - } - - public static int readIntegerParameter(InputStream is) throws IOException, ASAPException { - int value = 0; - value = readShortParameter(is); - value = value << 16; - - value = value & BLANK_RIGHT_INTEGER; - - int right = readShortParameter(is); - right = right & BLANK_LEFT_INTEGER; - - value += right; - - return value; - } - - public static long readLongParameter(InputStream is) throws IOException, ASAPException { - long value = readIntegerParameter(is); - value = value << 32; - value = value & BLANK_RIGHT_LONG; - - long right = readIntegerParameter(is); - right = right & BLANK_LEFT_LONG; - - value += right; - - return value; - } - - public static String readCharSequenceParameter(InputStream is) throws IOException, ASAPException { - int length = 0; - byte[] parameterBytes = null; - String lenString = null; -// try { - length = readIntegerParameter(is); - parameterBytes = new byte[length]; -/* - } - catch(OutOfMemoryError e) { - int i = 42; - throw new ASAPException(e); - } - */ - - is.read(parameterBytes); - - return new String(parameterBytes); - } - - public static void writeCharSequenceSetParameter(Set charSet, OutputStream os) throws IOException { - if (charSet == null || charSet.size() == 0) { - ASAPSerialization.writeNonNegativeIntegerParameter(0, os); - return; - } - - // more recipients - - // write len - ASAPSerialization.writeNonNegativeIntegerParameter(charSet.size(), os); - - // write entries - for (CharSequence entry : charSet) { - ASAPSerialization.writeCharSequenceParameter(entry, os); - } - } - - public static Set readCharSequenceSetParameter(InputStream is) throws IOException, ASAPException { - Set charSet = new HashSet<>(); - int len = ASAPSerialization.readIntegerParameter(is); - - while (len-- > 0) { - charSet.add(ASAPSerialization.readCharSequenceParameter(is)); - } - - return charSet; - } - - public static ASAPEncounterConnectionType readEncounterConnectionType(InputStream is) throws IOException, ASAPException { - byte readByte = ASAPSerialization.readByte(is); - switch (readByte) { - case 1: - return ASAPEncounterConnectionType.ASAP_HUB; - case 2: - return ASAPEncounterConnectionType.AD_HOC_LAYER_2_NETWORK; - case 3: - return ASAPEncounterConnectionType.ONION_NETWORK; - case 4: - return ASAPEncounterConnectionType.INTERNET; - default: - Log.writeLogErr(ASAPSerialization.class, "unknown encounter connection type: " + readByte); - } - // default - return ASAPEncounterConnectionType.UNKNOWN; - } - - public static void writeEncounterConnectionType(ASAPEncounterConnectionType connectionType, OutputStream os) throws IOException { - switch (connectionType) { - case ASAP_HUB: - ASAPSerialization.writeByteParameter((byte) 1, os); - break; - case AD_HOC_LAYER_2_NETWORK: - ASAPSerialization.writeByteParameter((byte) 2, os); - break; - case ONION_NETWORK: - ASAPSerialization.writeByteParameter((byte) 3, os); - break; - case INTERNET: - ASAPSerialization.writeByteParameter((byte) 4, os); - break; - case UNKNOWN: - default: - ASAPSerialization.writeByteParameter((byte) 0, os); - } - } - - public static void writeBooleanParameter(boolean value, OutputStream os) throws IOException { - if (value) ASAPSerialization.writeByteParameter((byte) 1, os); - else ASAPSerialization.writeByteParameter((byte) 0, os); - } - - public static boolean readBooleanParameter(InputStream is) throws IOException, ASAPException { - return ASAPSerialization.readByte(is) == 1; - } - - public static void writeASAPHop(ASAPHop asapHop, OutputStream os) throws IOException { - ASAPSerialization.writeCharSequenceParameter(asapHop.sender(), os); - ASAPSerialization.writeBooleanParameter(asapHop.verified(), os); - ASAPSerialization.writeBooleanParameter(asapHop.encrypted(), os); - ASAPSerialization.writeEncounterConnectionType(asapHop.getConnectionType(), os); - } - - public static byte[] asapHop2ByteArray(ASAPHop asapHop) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeASAPHop(asapHop, baos); - return baos.toByteArray(); - } - - public static byte[] asapHopList2ByteArray(List asapHops) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeASAPHopList(asapHops, baos); - return baos.toByteArray(); - } - - public static ASAPHop readASAPHop(InputStream is) throws IOException, ASAPException { - CharSequence sender = ASAPSerialization.readCharSequenceParameter(is); - boolean verified = ASAPSerialization.readBooleanParameter(is); - boolean encrypted = ASAPSerialization.readBooleanParameter(is); - ASAPEncounterConnectionType connectionType = ASAPSerialization.readEncounterConnectionType(is); - - return new ASAPHopImpl(sender, verified, encrypted, connectionType); - } - - public static ASAPHop byteArray2ASAPHop(byte[] bytes) throws IOException, ASAPException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - return readASAPHop(bais); - } - - public static List byteArray2ASAPHopList(byte[] bytes) throws IOException, ASAPException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - return readASAPHopList(bais); - } - - public static void writeASAPHopList(List asapHopList, OutputStream os) throws IOException { - if (asapHopList == null || asapHopList.isEmpty()) { - // no hops - ASAPSerialization.writeIntegerParameter(0, os); - return; - } - - // write number of hops - ASAPSerialization.writeIntegerParameter(asapHopList.size(), os); - for (ASAPHop asapHop : asapHopList) { - ASAPSerialization.writeASAPHop(asapHop, os); - } - } - - public static List readASAPHopList(InputStream is) throws IOException, ASAPException { - List asapHopList = new ArrayList<>(); - - int number = ASAPSerialization.readIntegerParameter(is); - while (number-- > 0) { - asapHopList.add(ASAPSerialization.readASAPHop(is)); - } - - return asapHopList; - - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/Batchprocessor.java b/src/main/java/net/sharksystem/asap/utils/Batchprocessor.java deleted file mode 100644 index 97cc5fc..0000000 --- a/src/main/java/net/sharksystem/asap/utils/Batchprocessor.java +++ /dev/null @@ -1,96 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalPeer; -import net.sharksystem.asap.cmdline.CmdLineUI; -import net.sharksystem.utils.Log; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; - -public class Batchprocessor implements Runnable { - List cmdList = new ArrayList<>(); - private CmdLineUI cmdLineUI; - private PrintStream printStream; - private ByteArrayInputStream inputStream; - private Thread runningThread; - - public Batchprocessor() { - this(true); - } - - public Batchprocessor(boolean cleanup) { - if(cleanup) { - Log.writeLog(this, "clean asap peers folders"); - this.cmdLineUI = new CmdLineUI(); - } - } - - public void setOutputstream(PrintStream ps) { - this.cmdLineUI.setOutStreams(ps); - } - - public void addCommand(String cmd) { - this.cmdList.add(cmd); - } - - public void execute() { - this.prepareExecution(); - this.doExecution(); - } - - public void executeAsThread() { - this.prepareExecution(); - this.runningThread = new Thread(this); - this.runningThread.start(); - } - - public void join() throws InterruptedException { - if(this.runningThread != null && this.runningThread.isAlive()) { - this.runningThread.join(); - } - } - - private void prepareExecution() { - // prepare output - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(baos); - - for(String cmd : this.cmdList) { - ps.println(cmd); - } - - // clean cmd list - this.cmdList = new ArrayList<>(); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - this.printStream = System.out; - this.inputStream = bais; - } - - private void doExecution() { - this.cmdLineUI.runCommandLoop(this.printStream, this.inputStream); - - // in any case - give it some time to tidy up - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // ignore - } - - this.runningThread = null; - } - - @Override - public void run() { - this.doExecution(); - } - - public ASAPInternalPeer getASAPPeer(String peerName) throws ASAPException { - return this.cmdLineUI.getASAPPeer(peerName); - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/DateTimeHelper.java b/src/main/java/net/sharksystem/asap/utils/DateTimeHelper.java deleted file mode 100644 index 2afcafa..0000000 --- a/src/main/java/net/sharksystem/asap/utils/DateTimeHelper.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.sharksystem.asap.utils; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class DateTimeHelper { - public static final long TIME_NOT_SET = -1; - - private static String guardNull(long longtime) { - if(longtime == TIME_NOT_SET) return "not set (yet)"; - else return null; - } - - public static String long2DateString(long longtime) { - String ret = guardNull(longtime); - if(ret != null) return ret; - - Date date = new Date(longtime); - return DateFormat.getInstance().format(date); - } - - public static String long2ExactTimeString(long longtime) { - String ret = guardNull(longtime); - if(ret != null) return ret; - - Date date = new Date(longtime); - DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - - return df.format(date); - } - - public static String nowAsStringMostSpecific() { - return long2ExactTimeString(System.currentTimeMillis()); - } -} diff --git a/src/main/java/net/sharksystem/asap/utils/PeerIDHelper.java b/src/main/java/net/sharksystem/asap/utils/PeerIDHelper.java deleted file mode 100644 index 3af3fff..0000000 --- a/src/main/java/net/sharksystem/asap/utils/PeerIDHelper.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sharksystem.asap.utils; - -import net.sharksystem.asap.ASAP; - -public class PeerIDHelper { - public static boolean sameID(CharSequence idA, CharSequence idB) { - if(idA == null && idB == null) return true; // both null - consider that same - - if(idA == null) return false; // obviously B is not null - not the same - if(idB == null) return false; // obviously A is not null - not the same - - if(idA.length() != idB.length()) return false; - - // same length - I take A - for(int i = 0; i < idA.length(); i++) { - if(idA.charAt(i) != idB.charAt(i)) return false; - } - - // no difference - return true; - } - - public static boolean sameFormat(CharSequence formatA, CharSequence formatB) { - return PeerIDHelper.sameID(formatA, formatB); - } - - public static boolean sameUri(CharSequence uriA, CharSequence uriB) { - return PeerIDHelper.sameID(uriA, uriB); - } - - public static String createUniqueID() { - return ASAP.createUniqueID(); - } -} diff --git a/src/main/java/net/sharksystem/fs/ExtraData.java b/src/main/java/net/sharksystem/fs/ExtraData.java deleted file mode 100644 index 695964c..0000000 --- a/src/main/java/net/sharksystem/fs/ExtraData.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sharksystem.fs; - -import net.sharksystem.SharkException; - -import java.io.IOException; -import java.util.Set; - -public interface ExtraData { - // remember a parameter with a key - void putExtra(CharSequence key, byte[] value) throws IOException, SharkException; - - void putExtra(CharSequence key, Integer value) throws IOException, SharkException; - - void putExtra(CharSequence key, CharSequence value) throws IOException, SharkException; - - void putExtra(CharSequence key, Set value) throws IOException, SharkException; - - /** get a parameter by a key - * - * @param key - * @return - * @throws IOException - * @throws SharkException if no such key exists - */ - byte[] getExtra(CharSequence key) throws IOException, SharkException; - - int getExtraInteger(CharSequence key) throws IOException, SharkException; - - Set getExtraCharSequenceSetParameter(CharSequence key) throws IOException, SharkException; - - String getExtraString(CharSequence key) throws IOException, SharkException; - // remove all data - void removeAll() throws IOException, SharkException; -} diff --git a/src/main/java/net/sharksystem/fs/ExtraDataFS.java b/src/main/java/net/sharksystem/fs/ExtraDataFS.java deleted file mode 100644 index 442ef49..0000000 --- a/src/main/java/net/sharksystem/fs/ExtraDataFS.java +++ /dev/null @@ -1,196 +0,0 @@ -package net.sharksystem.fs; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.*; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class ExtraDataFS implements ExtraData { - public static final String DEFAULT_FILE_NAME = ".extraData"; - private final CharSequence fileName; - private final CharSequence rootFolderName; - - private Map extraData = new HashMap<>(); - - public ExtraDataFS(CharSequence rootFolderName) throws SharkException, IOException { - this(rootFolderName, DEFAULT_FILE_NAME); - } - - public ExtraDataFS(CharSequence rootFolder, CharSequence fileName) throws IOException, SharkException { - this.rootFolderName = rootFolder; - // hide file in any case - if(fileName.charAt(0) != '.') this.fileName = "." + fileName; - else this.fileName = fileName; - File rootFolderFile = new File(rootFolder.toString()); - if(!rootFolderFile.exists()) { - // create - rootFolderFile.mkdirs(); - } - this.restoreExtraData(); - } - - private File getExtraFile() { - String extraFileName = this.rootFolderName + "/" + fileName; - return new File(extraFileName); - } - - /* - Here is the catch... There can be - and in Android will - two instances share data over file system. The use - same clock but run in different threads, most likely different processes. We have to synchronize both sides. - - There will be two processes A and B. Let's assume we are in process A. - a) We never written something, - - */ - - private long timeStampSyncExtraData = -1; // never saved anything - - private void extraDataSync() throws IOException, SharkException { - InputStream is = null; - try { - is = new FileInputStream(this.getExtraFile()); - } - catch(IOException ioEx) { - // no such file - save it instead - there is no conflict - this.saveExtraData(); - return; - } - - // read time stamp - long timeStampSaved = ASAPSerialization.readLongParameter(is); - - if(this.timeStampSyncExtraData < timeStampSaved) { - // there is an external copy that was created after our last sync - } - - // discard local changes and read from file - this.restoreExtraData(); - } - - public void saveExtraData() throws IOException { - OutputStream os = new FileOutputStream(this.getExtraFile()); - - // write time stamp - this.timeStampSyncExtraData = System.currentTimeMillis(); - ASAPSerialization.writeLongParameter(this.timeStampSyncExtraData, os); - ASAPSerialization.writeNonNegativeIntegerParameter(this.extraData.size(), os); - - for(CharSequence key : this.extraData.keySet()) { - // write key - ASAPSerialization.writeCharSequenceParameter(key, os); - // value - byte[] v = this.extraData.get(key); - ASAPSerialization.writeByteArray(v, os); - } - - os.close(); - } - - /** - * Always restore. If there is no such file - write it. - * @throws IOException - * @throws ASAPException - */ - public void restoreExtraData() throws IOException, SharkException { - InputStream is = null; - try { - is = new FileInputStream(this.getExtraFile()); - } - catch(IOException ioEx) { - // no such file - nothing to do here - return; - } - - long timeStampSaved = ASAPSerialization.readLongParameter(is); - if(timeStampSaved == this.timeStampSyncExtraData) { - is.close(); - return; - } - - // something changed - get a fresh copy - this.timeStampSyncExtraData = timeStampSaved; - - this.extraData = new HashMap<>(); - int counter = ASAPSerialization.readIntegerParameter(is); - - while(counter-- > 0) { - // read key - CharSequence key = ASAPSerialization.readCharSequenceParameter(is); - // value - byte[] value = ASAPSerialization.readByteArray(is); - - // save in memory - this.extraData.put(key, value); - } - is.close(); - } - - /** - * Make a value persistent with key - * @param key - * @param value - */ - public void putExtra(CharSequence key, byte[] value) throws IOException, SharkException { - this.extraDataSync(); - this.extraData.put(key, value); - this.saveExtraData(); - } - - @Override - public void putExtra(CharSequence key, Integer value) throws IOException, SharkException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeIntegerParameter(value, baos); - this.putExtra(key, baos.toByteArray()); - } - - @Override - public void putExtra(CharSequence key, CharSequence value) throws IOException, SharkException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeCharSequenceParameter(value, baos); - this.putExtra(key, baos.toByteArray()); - } - - public void putExtra(CharSequence key, Set value) throws IOException, SharkException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeCharSequenceSetParameter(value, baos); - this.putExtra(key, baos.toByteArray()); - } - - /** - * Return a value - can be null if null was set as value. - * @param key - * @throws ASAPException key never used in putExtra - */ - public byte[] getExtra(CharSequence key) throws IOException, SharkException { - this.restoreExtraData(); - byte[] value = this.extraData.get(key); - if(value == null) throw new SharkException("no value for key" + key); - return value; - } - - @Override - public int getExtraInteger(CharSequence key) throws IOException, SharkException { - ByteArrayInputStream bais = new ByteArrayInputStream(this.getExtra(key)); - return ASAPSerialization.readIntegerParameter(bais); - } - - @Override - public String getExtraString(CharSequence key) throws IOException, SharkException { - ByteArrayInputStream bais = new ByteArrayInputStream(this.getExtra(key)); - return ASAPSerialization.readCharSequenceParameter(bais); - } - - public Set getExtraCharSequenceSetParameter(CharSequence key) throws IOException, SharkException { - ByteArrayInputStream bais = new ByteArrayInputStream(this.getExtra(key)); - return ASAPSerialization.readCharSequenceSetParameter(bais); - } - - @Override - public void removeAll() { - this.getExtraFile().delete(); - } -} diff --git a/src/main/java/net/sharksystem/fs/FSUtils.java b/src/main/java/net/sharksystem/fs/FSUtils.java deleted file mode 100644 index 8182a61..0000000 --- a/src/main/java/net/sharksystem/fs/FSUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.sharksystem.fs; - -import net.sharksystem.utils.Log; - -import java.io.File; - -public class FSUtils { - //////////////////////////////////////////////////////////////////////////////////////// - // helper // - //////////////////////////////////////////////////////////////////////////////////////// - - public static void removeFolder(String eraPathName) { - File dir = new File(eraPathName); - - String[] dirEntries = dir.list(); - - if(dirEntries != null) { - for(String fileName : dirEntries) { - File fileInDir = new File(eraPathName + "/" + fileName); - if(fileInDir.isDirectory()) { - FSUtils.removeFolder(fileInDir.getAbsolutePath()); - } else { - try { - if(!fileInDir.delete()) { - Log.writeLog(FSUtils.class,"ASAPEngineFS: cannot delete file (try deleteOnExit):" - + fileInDir); - } - } catch (RuntimeException e) { - Log.writeLog(FSUtils.class, "cannot file:" + e.getLocalizedMessage()); - // try next - } - } - } - } - - dir.delete(); - //dir.deleteOnExit(); - try { - Thread.sleep(1); // give file system a moment - } catch (InterruptedException e) { - // nobody wants to know - } - } -} diff --git a/src/main/java/net/sharksystem/testhelper/ASAPTesthelper.java b/src/main/java/net/sharksystem/testhelper/ASAPTesthelper.java deleted file mode 100644 index 340dcf5..0000000 --- a/src/main/java/net/sharksystem/testhelper/ASAPTesthelper.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.sharksystem.testhelper; - -import net.sharksystem.utils.Log; -import net.sharksystem.utils.testsupport.TestHelper; - -public class ASAPTesthelper { - public static final String ALICE_ID = "Alice_ID"; - public static final String ALICE_NAME = "Alice"; - public static final String BOB_ID = "Bob_ID"; - public static final String BOB_NAME = "Bob"; - public static final String CLARA_ID = "Clara_ID"; - public static final String CLARA_NAME = "Clara"; - public static final String DAVID_ID = "David_ID"; - public static final String DAVID_NAME = "David"; - - public static final String ROOT_DIRECTORY_TESTS = "playground/"; - - public static int testNumber = 0; - - /** - * Create a fresh testNumber - */ - public static void incrementTestNumber() { - testNumber++; - } - - private static int portnumber = 7000; - /** - * Create a fresh TCP port. - * @return - */ - public static int getPortNumber() { - portnumber++; - return portnumber; - } - - public static final String getUniqueFolderName(String prefix) { - Log.writeLog(TestHelper.class, "test number == " + TestHelper.testNumber); - return prefix + "_" + ASAPTesthelper.testNumber; - } -} diff --git a/src/main/java/net/sharksystem/utils/AlarmClock.java b/src/main/java/net/sharksystem/utils/AlarmClock.java deleted file mode 100644 index f3754a8..0000000 --- a/src/main/java/net/sharksystem/utils/AlarmClock.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.sharksystem.utils; - -public class AlarmClock extends Thread { - public static final int DEFAULT_KEY = 42; - private final long duration; - private final int key; - private final AlarmClockListener listener; - private Thread thread; - private boolean killed = false; - - public AlarmClock(long duration, int key, AlarmClockListener listener) { - this.duration = duration; - this.key = key; - this.listener = listener; - } - - public AlarmClock(long duration, AlarmClockListener listener) { - this(duration, DEFAULT_KEY, listener); - } - - public void kill() { - this.killed = true; - } - - public void run() { - try { - // killed before started ? - if(!this.killed) { - Thread.sleep(duration); - } - - // killed during sleep? - if(!this.killed) { - this.listener.alarmClockRinging(this.key); - } - } catch (InterruptedException e) { - // interrupted - nothing to do - } - } - - public String toString() { - return "AlarmClock : " + this.key; - } -} diff --git a/src/main/java/net/sharksystem/utils/AlarmClockListener.java b/src/main/java/net/sharksystem/utils/AlarmClockListener.java deleted file mode 100644 index b74431d..0000000 --- a/src/main/java/net/sharksystem/utils/AlarmClockListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.sharksystem.utils; - -public interface AlarmClockListener { - void alarmClockRinging(int yourKey); -} diff --git a/src/main/java/net/sharksystem/utils/Commandline.java b/src/main/java/net/sharksystem/utils/Commandline.java deleted file mode 100644 index 2b00036..0000000 --- a/src/main/java/net/sharksystem/utils/Commandline.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.sharksystem.utils; - -import java.util.HashMap; - -public class Commandline { - public static HashMap parametersToMap(String args[], boolean valueRequired, String helpMessage) { - if(valueRequired && args.length % 2 != 0) { - System.err.println("malformed parameter list: each parameter needs a value. "); - System.err.println(helpMessage); - return null; - } - - HashMap argumentMap = new HashMap<>(); - - int i = 0; - while(i < args.length) { - // key is followed by value. Key starts with - - if(!args[i].startsWith("-")) { - /* found parameter that does not start with '-' - maybe shell parameters. Leave it alone. We are done here - */ - return argumentMap; - } - - // value can be empty - if(args.length > i+1 && !args[i+1].startsWith("-")) { - // it is a value - argumentMap.put(args[i], args[i+1]); - i += 2; - } else { - // no value - next parameter - argumentMap.put(args[i], null); - i += 1; - } - } - - return argumentMap; - } - - -} diff --git a/src/main/java/net/sharksystem/utils/Log.java b/src/main/java/net/sharksystem/utils/Log.java deleted file mode 100644 index 2e8fdcd..0000000 --- a/src/main/java/net/sharksystem/utils/Log.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.sharksystem.utils; - -import java.io.PrintStream; - -public class Log { - private static PrintStream outStream = System.out; - private static PrintStream errStream = System.err; - - public static void setOutStream(PrintStream outStream) { - Log.outStream = outStream; - } - - public static void setErrStream(PrintStream errStream) { - Log.errStream = errStream; - } - - public static StringBuilder startLog(Object o, String parameter) { - return startLog(o.getClass(), parameter); - } - - public static StringBuilder startLog(Object o) { - return startLog(o, null); - } - - public static StringBuilder startLog(Class c) { - return startLog(c, null); - } - - public static StringBuilder startLog(Class c, String parameter) { - StringBuilder sb = new StringBuilder(); - sb.append(c.getSimpleName()); - if(parameter != null && parameter.length() > 0) { - sb.append("("); - sb.append(parameter); - sb.append(")"); - } - sb.append(": "); - return sb; - } - - public static void writeLog(Object o, String parameter, String message) { - Log.outStream.println(Log.startLog(o, parameter) + message); - } - - public static void writeLog(Object o, CharSequence parameter, String message) { - Log.outStream.println(Log.startLog(o, String.valueOf(parameter)) + message); - } - - public static void writeLog(Object o, String message) { - writeLog(o, null, message); - } - - public static void writeLog(Class c, String parameter, String message) { - Log.outStream.println(Log.startLog(c, parameter) + message); - } - - public static void writeLog(Class c, String message) { - writeLog(c, null, message); - } - - public static void writeLogErr(Object o, String parameter, String message) { - Log.errStream.println(Log.startLog(o, parameter) + message); - } - - public static void writeLogErr(Object o, CharSequence parameter, String message) { - Log.errStream.println(Log.startLog(o, String.valueOf(parameter)) + message); - } - - public static void writeLogErr(Object o, String message) { - writeLogErr(o, null, message); - } - - public static void writeLogErr(Class c, String parameter, String message) { - Log.errStream.println(Log.startLog(c, parameter) + message); - } - - public static void writeLogErr(Class c, String message) { - writeLogErr(c, null, message); - } -} diff --git a/src/main/java/net/sharksystem/utils/SerializationHelper.java b/src/main/java/net/sharksystem/utils/SerializationHelper.java deleted file mode 100644 index aac2205..0000000 --- a/src/main/java/net/sharksystem/utils/SerializationHelper.java +++ /dev/null @@ -1,133 +0,0 @@ -package net.sharksystem.utils; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.*; -import java.util.*; - -public class SerializationHelper { - public static final String SERIALIZATION_DELIMITER = "|||"; - - public static String collection2String(Collection stringList) { - StringBuilder sb = new StringBuilder(); - - boolean first = true; - if(stringList != null && !stringList.isEmpty()) { - for(CharSequence s : stringList) { - if(s != null) { - if(!first) { - sb.append(SERIALIZATION_DELIMITER); - } else { - first = false; - } - sb.append(s); - } - } - } - - return sb.toString(); - } - - public static byte[] long2byteArray(long value) { - int numberBytes = Long.SIZE / 8; // A byte has 8 bits :) Fascinating, Captain. - byte[] result = new byte[numberBytes]; - - for(int index = numberBytes-1; index >= 0; index--) { - long mask = 0xFF; - // shift mask - mask = mask << index; - - // mask all but indexed byte - long resultLong = value & mask; - - // shift result to first byte - resultLong = resultLong >> index; - - // take first byte only - result[index] = (byte)resultLong; - } - - return result; - } - - public static byte[] characterSequence2bytes(CharSequence cs) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeCharSequenceParameter(cs, baos); - return baos.toByteArray(); - } - - public static CharSequence bytes2characterSequence(byte[] bytes) throws IOException, ASAPException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - return ASAPSerialization.readCharSequenceParameter(bais); - } - - public static List string2CharSequenceList(String s) { - StringTokenizer t = new StringTokenizer(s, SERIALIZATION_DELIMITER); - ArrayList list = new ArrayList(); - - while(t.hasMoreTokens()) { - list.add(t.nextToken()); - } - - return list; - } - - public static Set string2CharSequenceSet(String s) { - List charSequences = SerializationHelper.string2CharSequenceList(s); - Set charSet = new HashSet(); - for(CharSequence c : charSequences) { - charSet.add(c); - } - - return charSet; - } - - public static ArrayList set2arraylist(Set aSet) { - ArrayList aList = new ArrayList(); - if(aSet == null) return aList; - - for(Object o : aSet) { - aList.add(o); - } - - return aList; - } - - public static Set list2set(List aList) { - Set aSet = new HashSet(); - if(aList == null) return aSet; - - for(Object o : aList) { - aSet.add(o); - } - - return aSet; - } - - public static byte[] str2bytes(String msg) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream daos = new DataOutputStream(baos); - daos.writeUTF(msg); - - return baos.toByteArray(); - } - - public static String bytes2str(byte[] bytes) throws IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - DataInputStream daos = new DataInputStream(bais); - return daos.readUTF(); - } - - public static final boolean sameByteArray(byte[] a, byte[] b) { - if(a == null && b == null) return true; - if(a.length != b.length) return false; - - // not null, same length - for(int i = 0; i < a.length; i++) { - if(a[i] != b[i]) return false; - } - - return true; - } -} diff --git a/src/main/java/net/sharksystem/utils/Utils.java b/src/main/java/net/sharksystem/utils/Utils.java deleted file mode 100644 index 0a50da4..0000000 --- a/src/main/java/net/sharksystem/utils/Utils.java +++ /dev/null @@ -1,141 +0,0 @@ -package net.sharksystem.utils; - -import net.sharksystem.asap.ASAP; - -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.*; - -public class Utils { - public static String url2FileName(String url) { - // escape: - /* - see https://en.wikipedia.org/wiki/Percent-encoding - \ - %5C, / - %2F, : - %3A, ? - %3F," - %22,< - %3C,> - %3E,| - %7C - */ - - if(url == null) return null; // to be safe - - String newString = url.replace("\\", "%5C"); - newString = newString.replace("/", "%2F"); - newString = newString.replace(":", "%3A"); - newString = newString.replace("?", "%3F"); - newString = newString.replace("\"", "%22"); - newString = newString.replace("<", "%3C"); - newString = newString.replace(">", "%3E"); - newString = newString.replace("|", "%7C"); - - return newString; - } - - /** - * - * @param rootFolder - * @return collection of integer values depicting era present in that folder - */ - public static Collection getErasInFolder(String rootFolder) { - Collection eras = new HashSet<>(); - File dir = new File(rootFolder); - String[] dirEntries = dir.list(); - if (dirEntries != null) { - for (String fileName : dirEntries) { - // era folder? - try { - int era = Integer.parseInt(fileName); - // It is an era folder - eras.add(era); - } catch (NumberFormatException e) { - // no number - no problem - go ahead! - } - } - } - return eras; - } - - /** - * Return true if both collections contain same number of elements and for each element in a there is an - * identical element in b (String.compareTo()) - * in a has the "same" - * @param a - * @param b - * @return - */ - public static boolean sameContent(Collection a, Collection b) { - if(a == null && b == null) return true; - if(a == null) return false; // b is not null - if(b == null) return false; // a is not null - // bot not null - if(a.size() != b.size()) return false; - - for(CharSequence aElement : a) { - String aString = aElement.toString(); - boolean found = false; - Iterator bIterator = b.iterator(); - while(bIterator.hasNext() && !found) { - String bString = bIterator.next().toString(); - if(bString.compareTo(aString) == 0) found = true; - } - if(!found) return false; - } - - return true; - } - - public static boolean compareArrays(byte[] a, byte[] b) { - if(a.length != b.length) { - Log.writeLog(net.sharksystem.utils.Utils.class, "not same length"); - return false; - } - - if(a.length == 0) { - Log.writeLog(net.sharksystem.utils.Utils.class, "len zero"); - return false; - } - - for(int i = 0; i < a.length; i++) { - Log.writeLog(net.sharksystem.utils.Utils.class, i + ": " + a[i] + " == " + b[i]); - if(a[i] != b[i]) { - Log.writeLog(net.sharksystem.utils.Utils.class, "no longer same"); - return false; - } - } - - return true; - } - - public static String byteArray2String(byte[] b) { - if(b == null) return "null"; - - StringBuilder sb = new StringBuilder(); - sb.append("len == "); - sb.append(b.length); - sb.append("; content == ("); - for(int i = 0; i < b.length; i++) { - if(i != 0) sb.append(", "); - sb.append(b); - } - sb.append(")"); - - return sb.toString(); - } - - public static String calendar2String(Calendar calendarObject) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z"); - return dateFormat.format(calendarObject.getTime()); - } - - public static String getStringByStringList(List list) { - if(list == null || list.isEmpty()) return "empty list"; - StringBuilder sb = new StringBuilder(); - int i = 0; - boolean first = true; - for(String o : list) { - if(first) first = false; - else sb.append(", "); - sb.append(i++); - sb.append(": "); - sb.append(o); - } - return sb.toString(); - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/IdleStreamPairCloser.java b/src/main/java/net/sharksystem/utils/streams/IdleStreamPairCloser.java deleted file mode 100644 index 8a405e4..0000000 --- a/src/main/java/net/sharksystem/utils/streams/IdleStreamPairCloser.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.sharksystem.utils.streams; - -import net.sharksystem.utils.AlarmClock; -import net.sharksystem.utils.AlarmClockListener; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class IdleStreamPairCloser implements AlarmClockListener, WrappedStreamPairListener { - private final int timeout; - private StreamPairWrapper streamPairWrapper; - private AlarmClock alarmClock; - - private IdleStreamPairCloser(int timeout) { - this.timeout = timeout; - } - - public static IdleStreamPairCloser getIdleStreamsCloser(StreamPair streamPair, int timeout) throws IOException { - // create object that also becomes listener - IdleStreamPairCloser idleStreamPairCloser = new IdleStreamPairCloser(timeout); - - // create wrapper with listener - StreamPairWrapper streamPairWrapper = new StreamPairWrapper( - streamPair.getInputStream(), streamPair.getOutputStream(), idleStreamPairCloser, "X"); - - // now: put wrapper into listener - idleStreamPairCloser.setStreamPairWrapper(streamPairWrapper); - return idleStreamPairCloser; - } - - public InputStream getInputStream() { - return this.streamPairWrapper.getInputStream(); - } - - public OutputStream getOutputStream() { - return this.streamPairWrapper.getOutputStream(); - } - - public StreamPair getStreamPair() { - return this.streamPairWrapper; - } - - void setStreamPairWrapper(StreamPairWrapper streamPairWrapper) { - this.streamPairWrapper = streamPairWrapper; - } - - public void start() { - // give it more time in the first round - there will be a connection establishment process on its way... - this.alarmClock = new AlarmClock(this.timeout * 2, this); - } - - @Override - public void alarmClockRinging(int i) { - try { - this.streamPairWrapper.getInputStream().close(); - } catch (IOException e) { - // ignore - } - } - - @Override - public void notifyClosed(StreamPair streamPair, String s) { - this.alarmClock.kill(); // nothing todo. - this.alarmClock = null; - } - - @Override - public void notifyAction(String s) { - if(alarmClock != null) { - this.alarmClock.kill(); - this.alarmClock = new AlarmClock(timeout, this); - } // else not yet started - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamLink.java b/src/main/java/net/sharksystem/utils/streams/StreamLink.java deleted file mode 100644 index 0d9e7a0..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamLink.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.sharksystem.utils.streams; - -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class StreamLink extends Thread { - private final InputStream sourceIS; - private final OutputStream targetOS; - private final boolean closeStreams; - private String id = "anon"; - - public StreamLink(InputStream sourceIS, OutputStream targetOS, boolean closeStreams, String id) { - this.sourceIS = sourceIS; - this.targetOS = targetOS; - this.closeStreams = closeStreams; - this.id = id; - } - - StreamLink(InputStream sourceIS, OutputStream targetOS, boolean closeStreams) { - this(sourceIS, targetOS, closeStreams, "no id"); - } - - public void close() { - this.again = false; - } - - private boolean again = true; - - public void run() { - Log.writeLog(this, this.toString(), "start read/write loop"); - try { - int singleReadCounter = 0; - int read = -1; - do { - int available = sourceIS.available(); - //Log.writeLog(this, this.toString(), "available: " + available); - if (available > 0) { - singleReadCounter = 0; - byte[] buffer = new byte[available]; - sourceIS.read(buffer); - targetOS.write(buffer); - //Log.writeLog(this, this.toString(), ASAPSerialization.printByteArrayToString(buffer) - // + " end buffer:\n"); - } else { - // block - //Log.writeLog(this, this.toString(), "going to block in read(): "); - read = sourceIS.read(); - if(read != -1) { - /* - Log.writeLog(this, this.toString(), "read != -1 (" + ++singleReadCounter + ")"); - Log.writeLog(this, this.toString(), ASAPSerialization.printByteToString((short) read) - + " end byte"); - */ - targetOS.write(read); - } else { - //Log.writeLog(this, this.toString(), "read -1 - end"); - again = false; - } - } - } while (again); - } catch (IOException e) { - Log.writeLog(this, this.toString(), "ioException - most probably connection closed: " + id); - } finally { - if(this.closeStreams) { - Log.writeLog(this, this.toString(), "try closing linked streams: " + id); - try {this.targetOS.close();} - catch (IOException ioException) { Log.writeLog(this, this.toString(), "failed close input stream: " + id); } - try {this.sourceIS.close();} - catch (IOException ioException) { Log.writeLog(this, this.toString(), "failed close output stream: " + id); } - } - - Log.writeLog(this, this.toString(), "end linked streams connection: " + id); - } - } - - public String toString() { - return this.id; - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPair.java b/src/main/java/net/sharksystem/utils/streams/StreamPair.java deleted file mode 100644 index 19f8a15..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPair.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.sharksystem.utils.streams; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public interface StreamPair { - /** InputStream to read data from the other side */ - InputStream getInputStream() throws IOException; - /** OutputStream to send data to the other side */ - OutputStream getOutputStream() throws IOException; - /** close connection to peer */ - void close(); - - void addListener(StreamPairListener listener); - - CharSequence getSessionID(); - - CharSequence getEndpointID(); - - void setEndpointID(CharSequence peerID); -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPairImpl.java b/src/main/java/net/sharksystem/utils/streams/StreamPairImpl.java deleted file mode 100644 index 3cb925f..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPairImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.sharksystem.utils.streams; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class StreamPairImpl extends StreamPairListenerManager implements StreamPair { - private final InputStream is; - private final OutputStream os; - private final CharSequence sessionID; - private CharSequence endpointID; - - public static final String NO_ID = "no ID"; - - public static StreamPair getStreamPair(InputStream is, OutputStream os) { - return new StreamPairImpl(is, os, NO_ID, NO_ID); - } - - public static StreamPair getStreamPair(InputStream is, OutputStream os, - CharSequence sessionID, CharSequence endpointAddress) { - return new StreamPairImpl(is, os, sessionID, endpointAddress); - } - - public static StreamPair getStreamPairWithSessionID(InputStream is, OutputStream os, CharSequence sessionID) { - return new StreamPairImpl(is, os, sessionID, NO_ID); - } - - public static StreamPair getStreamPairWithEndpointAddress(InputStream is, OutputStream os, - CharSequence endpointAddress) { - return new StreamPairImpl(is, os, NO_ID, endpointAddress); - } - - /** - * Create a pair of in- and output streams (most probably a kind of socket) with an ID. This ID should be - * an endpoint address, e.g. a mac address, IP/TCP - address. It could also be an ASAP peer ID. - * @param is - * @param os - * @param sessionID a session id - */ - private StreamPairImpl(InputStream is, OutputStream os, CharSequence sessionID, CharSequence endpointAddress) { - this.sessionID = sessionID; - this.endpointID = endpointAddress; - this.is = is; - this.os = os; - } - - @Override - public InputStream getInputStream() { return this.is; } - - @Override - public OutputStream getOutputStream() { return this.os; } - - public CharSequence getSessionID() { - return this.sessionID; - } - - public CharSequence getEndpointID() { - return this.endpointID; - } - - public void setEndpointID(CharSequence endpointID) { - this.endpointID = endpointID; - } - - @Override - public void close() { - try { - is.close(); - } catch (IOException e) { - // ignore - } - try { - os.close(); - } catch (IOException e) { - // ignore - } - - if(this.sessionID != null) this.notifyAllListenerClosed(this, this.sessionID.toString()); - } - - public String toString() { - return "StreamPair (session: " + this.sessionID + " | endpoint: " + this.endpointID + ")"; - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPairLink.java b/src/main/java/net/sharksystem/utils/streams/StreamPairLink.java deleted file mode 100644 index c942494..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPairLink.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.sharksystem.utils.streams; - -import net.sharksystem.utils.Log; - -import java.io.IOException; - -public class StreamPairLink implements StreamPairListener { - private StreamLink streamLinkA2B; - private StreamLink streamLinkB2A; - - public StreamPairLink(StreamPair pairA, CharSequence idA, StreamPair pairB, CharSequence idB) throws IOException { - this(pairA, idA, pairB, idB, true); - } - - public StreamPairLink( - StreamPair pairA, CharSequence idA, - StreamPair pairB, CharSequence idB, - boolean autostart) throws IOException { - String tagA2B = idB + " ==> " + idA; - this.streamLinkA2B = new StreamLink(pairA.getInputStream(), pairB.getOutputStream(), true, tagA2B); - String tagB2A = idA + " ==> " + idB; - this.streamLinkB2A = new StreamLink(pairB.getInputStream(), pairA.getOutputStream(), true, tagB2A); - - // listen to close - pairA.addListener(this); - pairB.addListener(this); - - if(autostart) this.start(); - } - - @Override - public void notifyClosed(StreamPair closedStreamPair, String key) { - Log.writeLog(this, "stream pair closed: " + key); - this.streamLinkA2B.close(); - this.streamLinkB2A.close(); - } - - public void start() { - this.streamLinkA2B.start(); - this.streamLinkB2A.start(); - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPairListener.java b/src/main/java/net/sharksystem/utils/streams/StreamPairListener.java deleted file mode 100644 index 8e5b656..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPairListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.sharksystem.utils.streams; - -public interface StreamPairListener { - /** stream was closed - * @param closedStreamPair - * @param key*/ - void notifyClosed(StreamPair closedStreamPair, String key); -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPairListenerManager.java b/src/main/java/net/sharksystem/utils/streams/StreamPairListenerManager.java deleted file mode 100644 index 34c0316..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPairListenerManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.sharksystem.utils.streams; - -import java.util.ArrayList; -import java.util.List; - -public class StreamPairListenerManager { - protected List listenerList = new ArrayList<>(); - - public void addListener(StreamPairListener listener) { - this.listenerList.add(listener); - } - - protected void notifyAllListenerClosed(StreamPair closedStreamPair, String key) { - for(StreamPairListener listener : this.listenerList) { - (new Thread(new Runnable() { - @Override - public void run() { - listener.notifyClosed(closedStreamPair, key); - } - })).start(); - } - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/StreamPairWrapper.java b/src/main/java/net/sharksystem/utils/streams/StreamPairWrapper.java deleted file mode 100644 index b56650c..0000000 --- a/src/main/java/net/sharksystem/utils/streams/StreamPairWrapper.java +++ /dev/null @@ -1,137 +0,0 @@ -package net.sharksystem.utils.streams; - -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class StreamPairWrapper extends StreamPairListenerManager implements StreamPair { - private final InputStreamWrapper is; - private final OutputStreamWrapper os; - private String endpointAddress; - - /** - * @param is - * @param os - * @param listener - * @param endpointAddress - */ - public StreamPairWrapper(InputStream is, OutputStream os, WrappedStreamPairListener listener, String endpointAddress) { - this.is = new InputStreamWrapper(is); - this.os = new OutputStreamWrapper(os); - this.endpointAddress = endpointAddress; - super.addListener(listener); - - } - - public StreamPairWrapper(InputStream is, OutputStream os) { - this(is, os, null, "0"); - } - - @Override - public InputStream getInputStream() { - return this.is; - } - - @Override - public OutputStream getOutputStream() { - return this.os; - } - - @Override - public void close() { - // do not close the streams but prevent any further communication - Log.writeLog(this, "closed"); - this.is.closed = true; - this.os.closed = true; - this.notifyAllListenerClosed(this, this.endpointAddress); - /* - if(!this.listenerList.isEmpty()) { - for(WrappedStreamPairListener listener : this.listenerList) { - listener.notifyClosed(this.id); - } - } - */ - } - - @Override - public CharSequence getEndpointID() { - return this.endpointAddress; - } - - @Override - public void setEndpointID(CharSequence peerID) { - this.endpointAddress = peerID.toString(); - } - - @Override - public CharSequence getSessionID() { - return StreamPairImpl.NO_ID; - } - - private void notifyAction() { - if(!this.listenerList.isEmpty()) { - for(StreamPairListener listener : this.listenerList) { - if(listener instanceof WrappedStreamPairListener) { - WrappedStreamPairListener wrappedListener = (WrappedStreamPairListener) listener; - wrappedListener.notifyAction(this.endpointAddress); - } - } - } - } - - public void addListener(WrappedStreamPairListener listener) { - - } - - private class InputStreamWrapper extends InputStream { - private final InputStream is; - private boolean closed = false; - - InputStreamWrapper(InputStream is) { - this.is = is; - } - - @Override - public int read() throws IOException { - if(this.closed) throw new IOException("wrapped stream closed"); - int i = this.is.read(); - if(this.closed) { - Log.writeLog(this, "read sign after already closed " + i); - throw new IOException("wrapped stream closed"); - } - // else - StreamPairWrapper.this.notifyAction(); - return i; - } - - public void close() { - StreamPairWrapper.this.close(); - } - } - - private class OutputStreamWrapper extends OutputStream { - private final OutputStream os; - private boolean closed = false; - - OutputStreamWrapper(OutputStream os) { - this.os = os; - } - - @Override - public void write(int value) throws IOException { - if(this.closed) throw new IOException("wrapped stream closed"); - this.os.write(value); - StreamPairWrapper.this.notifyAction(); - } - - public void close() { - StreamPairWrapper.this.close(); - } - } - - public String toString() { - return this.endpointAddress; - } -} diff --git a/src/main/java/net/sharksystem/utils/streams/WrappedStreamPairListener.java b/src/main/java/net/sharksystem/utils/streams/WrappedStreamPairListener.java deleted file mode 100644 index 622b681..0000000 --- a/src/main/java/net/sharksystem/utils/streams/WrappedStreamPairListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sharksystem.utils.streams; - -public interface WrappedStreamPairListener extends StreamPairListener { - /** data read or written - * @param key*/ - void notifyAction(String key); -} diff --git a/src/main/java/net/sharksystem/utils/tcp/SocketFactory.java b/src/main/java/net/sharksystem/utils/tcp/SocketFactory.java deleted file mode 100644 index ea5d797..0000000 --- a/src/main/java/net/sharksystem/utils/tcp/SocketFactory.java +++ /dev/null @@ -1,146 +0,0 @@ -package net.sharksystem.utils.tcp; - -//import net.sharksystem.asap.ASAPEncounterHelper; - -import net.sharksystem.utils.Log; -import net.sharksystem.utils.streams.StreamPairImpl; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; - -public class SocketFactory implements Runnable { - private final ServerSocket srv; - private boolean remainOpen = false; - private int port = 0; - private StreamPairCreatedListener listener = null; - InputStream is; - OutputStream os; - private Thread waitForConnectionThread = null; - private String remoteAddress; - - public SocketFactory(int portNumber, StreamPairCreatedListener listener, boolean remainOpen) throws IOException { - this(new ServerSocket(portNumber)); - this.port = portNumber; - this.listener = listener; - this.remainOpen = remainOpen; - } - - public SocketFactory(int portNumber, StreamPairCreatedListener listener) throws IOException { - this(portNumber, listener, false); - } - - public SocketFactory(ServerSocket srv) { - this.srv = srv; - } - - /** - * Close server socket - kills thread already running - */ - public void close() throws IOException { - Log.writeLog(this, "close TCP server socket - do long longer accept connection attempts on port: " + this.port); - this.remainOpen = false; // looks nice but killing the socket will produce an IOException anyway - this.srv.close(); - } - - private boolean running = false; - @Override - public void run() { - this.running = true; - Log.writeLog(this,"socket factory running - accept connections on port: " + this.port); - if(!this.remainOpen) Log.writeLog(this,"only one connection will be handled on port: " + this.port - + " ( set option remainOpen == true for another behaviour)"); - try { - do { - Socket socket = srv.accept(); - this.is = socket.getInputStream(); - this.os = socket.getOutputStream(); - this.remoteAddress = SocketFactory.getRemoteAddress(socket); - Log.writeLog(this, "connection attempt accepted: socket created"); - if (this.waitForConnectionThread != null) { - //this.waitForConnectionThread.interrupt(); - this.waitForConnectionThread.notify(); - } - if (this.listener != null) { - this.listener.streamPairCreated( - StreamPairImpl.getStreamPairWithEndpointAddress(this.is, this.os, this.remoteAddress)); - } - Log.writeLog(this, "resume waiting for new connections on port " + this.port); - } while(this.remainOpen); - } catch (IOException e) { - if(!remainOpen) { - Log.writeLog(this, "socket factory terminated, closed port " + this.port); - } else { - Log.writeLogErr(this, "socket factory terminated but not from an app(?): " - + e.getLocalizedMessage()); - } - - } - } - - public InputStream getInputStream() throws IOException { - if (this.is == null) { - if(!running) { - throw new IOException("start factory thread first"); - } - this.waitForConnectionThread = Thread.currentThread(); - try { - //Thread.sleep(Long.MAX_VALUE); - this.waitForConnectionThread.wait(); - } catch (InterruptedException e) { - // great - do it again - return this.getInputStream(); - } - } - - return this.is; - } - - public OutputStream getOutputStream() throws IOException { - if (this.os == null) { - if(!running) { - throw new IOException("start factory thread first"); - } - this.waitForConnectionThread = Thread.currentThread(); - try { - //Thread.sleep(Long.MAX_VALUE); - this.waitForConnectionThread.wait(); - } catch (InterruptedException e) { - // great - do it again - return this.getOutputStream(); - } - } - - return this.os; - } - - public String getRemoteAddress() throws IOException { - if (this.os == null) { - if(!running) { - throw new IOException("start factory thread first"); - } - this.waitForConnectionThread = Thread.currentThread(); - try { - //Thread.sleep(Long.MAX_VALUE); - this.waitForConnectionThread.wait(); - } catch (InterruptedException e) { - // great - do it again - } - } - - return this.remoteAddress; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - // other useful stuff // - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - public static final String getRemoteAddress(Socket connectedSocket) throws IOException { - InetAddress inetAddress = connectedSocket.getInetAddress(); - int port = connectedSocket.getPort(); - return inetAddress.getHostAddress() + ":" + port; - } - -} diff --git a/src/main/java/net/sharksystem/utils/tcp/StreamPairCreatedListener.java b/src/main/java/net/sharksystem/utils/tcp/StreamPairCreatedListener.java deleted file mode 100644 index 11eec7e..0000000 --- a/src/main/java/net/sharksystem/utils/tcp/StreamPairCreatedListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sharksystem.utils.tcp; - -import net.sharksystem.utils.streams.StreamPair; - -public interface StreamPairCreatedListener { - void streamPairCreated(StreamPair streamPair); -} diff --git a/src/main/java/net/sharksystem/utils/testsupport/ASAPMessageReceivedStorage.java b/src/main/java/net/sharksystem/utils/testsupport/ASAPMessageReceivedStorage.java deleted file mode 100644 index b1a3187..0000000 --- a/src/main/java/net/sharksystem/utils/testsupport/ASAPMessageReceivedStorage.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.sharksystem.utils.testsupport; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessageReceivedListener; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.utils.Log; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class ASAPMessageReceivedStorage implements ASAPMessageReceivedListener { - public List messageStorage = new ArrayList<>(); - @Override - public void asapMessagesReceived(ASAPMessages messages, String senderE2E, List asapHops) throws IOException { - Log.writeLog(this, "messages received"); - if(messages != null) { - Iterator messagesIter = messages.getMessages(); - while(messagesIter.hasNext()) { - this.messageStorage.add(messagesIter.next()); - } - } - } - - public int getNumberReceivedMessages() { - return this.messageStorage.size(); - } -} diff --git a/src/main/java/net/sharksystem/utils/testsupport/TestConstants.java b/src/main/java/net/sharksystem/utils/testsupport/TestConstants.java deleted file mode 100644 index 3f52265..0000000 --- a/src/main/java/net/sharksystem/utils/testsupport/TestConstants.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.sharksystem.utils.testsupport; - -public interface TestConstants { - String ROOT_DIRECTORY = "testResultsRootFolder/"; - String ALICE_ID = "Alice_42"; - String ALICE_NAME = "Alice"; - String BOB_ID = "Bob_43"; - String BOB_NAME = "Bob"; - String CLARA_ID = "Clara_44"; - String CLARA_NAME = "Clara"; - String DAVID_ID = "David_45"; - String DAVID_NAME = "David"; - - String TEST_APP_FORMAT = "application/sn2"; - String URI = "shark://testUri"; - byte[] MESSAGE_1 = "1st message".getBytes(); - byte[] MESSAGE_2 = "2nd message".getBytes(); - - byte[] MESSAGE_ALICE_TO_BOB_1 = "Alice -> Bob (#1)".getBytes(); - byte[] MESSAGE_ALICE_TO_BOB_2 = "Alice -> Bob (#2)".getBytes(); - byte[] MESSAGE_BOB_TO_ALICE_1 = "Bob -> Alice (#1)".getBytes(); - byte[] MESSAGE_BOB_TO_ALICE_2 = "Bob -> Alice (#2)".getBytes(); - byte[] MESSAGE_CLARA_TO_ALICE_1 = "Clara -> Alice (#1)".getBytes(); - byte[] MESSAGE_CLARA_TO_ALICE_2 = "Clara -> Alice (#2)".getBytes(); -} diff --git a/src/main/java/net/sharksystem/utils/testsupport/TestHelper.java b/src/main/java/net/sharksystem/utils/testsupport/TestHelper.java deleted file mode 100644 index 9919ecc..0000000 --- a/src/main/java/net/sharksystem/utils/testsupport/TestHelper.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.sharksystem.utils.testsupport; - -import net.sharksystem.utils.Utils; -import net.sharksystem.fs.FSUtils; - -public class TestHelper { - public static int testNumber = 0; - public static int portNumber = 4444; - - public static int getPortNumber() { - portNumber++; - //System.out.println(">>>>>>>>>>>>>>>> portnumber: " + portNumber); - return portNumber; - } - - public static String getFullTempFolderName(String fullRootFolderName, boolean increment) { -// String retVal = fullRootFolderName + "_" + testNumber; - String retVal = TestConstants.ROOT_DIRECTORY + "/" + fullRootFolderName + "/test_" + testNumber; - if(increment) testNumber++; - return retVal; - } - - public static String getFullRootFolderName(String peerID, Class testClass) { - return testClass.getSimpleName() - + "/" - + peerID; - } - - public static void incrementTestNumber() { - testNumber++; - } - - public static String produceTestAppName(Class testClass) { - return "application/x-" + testClass.getSimpleName(); - } - - public static int testMessageCounter = 0; - - /** - * Produce a test message - just some bytes - Note: This methods return a different message - * after each call. - * @return - */ - public static byte[] produceTestMessage() { - String s = "testMessage" + testMessageCounter++; - return s.getBytes(); - } - - public static boolean sameMessages(byte[] msgA, byte[] msgB) { - return Utils.compareArrays(msgA, msgB); - } - - public static void removeFolder(String foldername) { - FSUtils.removeFolder(foldername); - } -} diff --git a/src/test/java/bugreports/BugReports.java b/src/test/java/bugreports/BugReports.java deleted file mode 100644 index 3d41ec7..0000000 --- a/src/test/java/bugreports/BugReports.java +++ /dev/null @@ -1,21 +0,0 @@ -package bugreports; - -import org.junit.Test; - -/** - * Any bug reports is very welcome and appreciated. - */ -public class BugReports { - @Test - public void perfectSoftware() { - System.out.println("There is no such thing as perfect software. It is only less buggy. Thanks for any help."); - } - - /** - * Add your report here - thank you - */ - @Test - public void yourBugReport() { - System.out.println("Thanks for helping!!"); - } -} diff --git a/src/test/java/bugreports/ConnectPeersMultiHopTest.java b/src/test/java/bugreports/ConnectPeersMultiHopTest.java deleted file mode 100644 index 9e0df21..0000000 --- a/src/test/java/bugreports/ConnectPeersMultiHopTest.java +++ /dev/null @@ -1,191 +0,0 @@ -package bugreports; - -import net.sharksystem.CountsReceivedMessagesListener; -import net.sharksystem.SharkException; -import net.sharksystem.asap.*; -import net.sharksystem.asap.apps.TCPServerSocketAcceptor; -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.streams.StreamPairImpl; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.BeforeEach; - -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; - - -/** - * This class is a bug report for sending multi-hop messages. - * There are three peers: Alice, Bob, and Clara. Alice and Clara are connected to Bob, - * but Alice and Clara aren't connected to each other directly. - * - * Alice sends a message to Bob, and Bob forwards it to Clara. - * - * The first test demonstrates the bug: - * If the message is sent after Alice and Clara have established connections to Bob and handled the encounter, - * the message is only received by Bob and is not forwarded to Clara. - * - * At the second test, clara handles the connection to Bob after the message from Alice was received by Bob. - * The message is received by Bob and forwarded to Clara. - */ -public class ConnectPeersMultiHopTest { - - private static final String TEST_FOLDER = "ConnectPeers"; - private final CharSequence EXAMPLE_APP_FORMAT = "shark/x-connectPeersExample"; - - private ASAPConnectionHandler alice; - private ASAPConnectionHandler bob; - private ASAPConnectionHandler clara; - - private ASAPEncounterManager aliceEncounterManager; - private ASAPEncounterManager bobEncounterManager; - private ASAPEncounterManager claraEncounterManager; - - @BeforeAll - public static void removePreviousTestFolder() { - FSUtils.removeFolder(TestConstants.ROOT_DIRECTORY + TEST_FOLDER); - } - - @BeforeEach - public void setUp() throws IOException, SharkException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(EXAMPLE_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peers - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - alice = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - // set up clara - String claraFolder = rootFolder + "/" + TestConstants.CLARA_ID; - clara = new ASAPPeerFS(TestConstants.CLARA_ID, claraFolder, formats); - - aliceEncounterManager = new ASAPEncounterManagerImpl(alice, TestConstants.ALICE_ID); - bobEncounterManager = new ASAPEncounterManagerImpl(bob, TestConstants.BOB_ID); - claraEncounterManager = new ASAPEncounterManagerImpl(clara, TestConstants.CLARA_ID); - } - - @Test - public void sendMessageMultiHopBug() throws IOException, SharkException, InterruptedException { - - ////////////////////////// set up server socket and handle connection requests - int portNumberAlice = TestHelper.getPortNumber(); - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberAlice, aliceEncounterManager); - - int portNumberBob = TestHelper.getPortNumber(); - TCPServerSocketAcceptor bobTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberBob, bobEncounterManager); - - // create second port for Bob, so that alice and clara can connect to Bob - int portNumberBob2 = TestHelper.getPortNumber(); - TCPServerSocketAcceptor bobTcpServerSocketAcceptor2 = - new TCPServerSocketAcceptor(portNumberBob2, bobEncounterManager); - - // setup message received listeners for bob and clara - ASAPPeerFS bobPeerFS = (ASAPPeerFS) bob; - CountsReceivedMessagesListener messageReceivedListenerBob = new CountsReceivedMessagesListener(TestConstants.BOB_ID); - bobPeerFS.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, messageReceivedListenerBob); - - ASAPPeerFS claraPeerFS = (ASAPPeerFS) clara; - CountsReceivedMessagesListener messageReceivedListenerClara = new CountsReceivedMessagesListener(TestConstants.CLARA_ID); - claraPeerFS.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, messageReceivedListenerClara); - - // give it a moment to settle - Thread.sleep(5); - - // now, bob opens two server sockets - one for alice and one for clara - // open connection to Bob - Socket socketAliceToBob = new Socket("localhost", portNumberBob); - Socket socketClaraToBob = new Socket("localhost", portNumberBob2); - - - // let Alice handle it - aliceEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketAliceToBob.getInputStream(), socketAliceToBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - // let clara handle it - claraEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketClaraToBob.getInputStream(), socketClaraToBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - // give it a moment to run ASAP session - Thread.sleep(5000); - - // send message from Alice to Bob after peers handled the connection - ASAPPeerFS alicePeerFS = (ASAPPeerFS) alice; - alicePeerFS.sendASAPMessage(EXAMPLE_APP_FORMAT, "my-uri", "Hello Bob!".getBytes()); - - // give it a moment for processing messages - Thread.sleep(2000); - - Assertions.assertTrue(messageReceivedListenerBob.numberOfMessages > 0); - Assertions.assertTrue(messageReceivedListenerClara.numberOfMessages > 0); - } - - - @Test - public void sendMessageMultiHopGood() throws IOException, SharkException, InterruptedException { - - ////////////////////////// set up server socket and handle connection requests - int portNumberAlice = TestHelper.getPortNumber(); - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberAlice, aliceEncounterManager); - - int portNumberBob = TestHelper.getPortNumber(); - TCPServerSocketAcceptor bobTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberBob, bobEncounterManager); - - // create second port for Bob, so that alice and clara can connect to Bob - int portNumberBob2 = TestHelper.getPortNumber(); - TCPServerSocketAcceptor bobTcpServerSocketAcceptor2 = - new TCPServerSocketAcceptor(portNumberBob2, bobEncounterManager); - - // setup message received listeners for bob and clara - ASAPPeerFS bobPeerFS = (ASAPPeerFS) bob; - CountsReceivedMessagesListener messageReceivedListenerBob = new CountsReceivedMessagesListener(TestConstants.BOB_ID); - bobPeerFS.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, messageReceivedListenerBob); - - ASAPPeerFS claraPeerFS = (ASAPPeerFS) clara; - CountsReceivedMessagesListener messageReceivedListenerClara = new CountsReceivedMessagesListener(TestConstants.CLARA_ID); - claraPeerFS.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, messageReceivedListenerClara); - - // give it a moment to settle - Thread.sleep(5); - - // now, bob opens two server sockets - one for alice and one for clara - // open connection to Bob - Socket socketAliceToBob = new Socket("localhost", portNumberBob); - Socket socketClaraToBob = new Socket("localhost", portNumberBob2); - - ASAPPeerFS alicePeerFS = (ASAPPeerFS) alice; - alicePeerFS.sendASAPMessage(EXAMPLE_APP_FORMAT, "my-uri", "Hello Bob!".getBytes()); - // let Alice handle it - aliceEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketAliceToBob.getInputStream(), socketAliceToBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - - Thread.sleep(2000); - Assertions.assertTrue(messageReceivedListenerBob.numberOfMessages > 0); - - // handle connection after message from alice was received by bob - claraEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketClaraToBob.getInputStream(), socketClaraToBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - - // give it a moment to run ASAP session - Thread.sleep(2000); - Assertions.assertTrue(messageReceivedListenerClara.numberOfMessages > 0); - } - -} \ No newline at end of file diff --git a/src/test/java/bugreports/snm_20/SNMReport20.java b/src/test/java/bugreports/snm_20/SNMReport20.java deleted file mode 100644 index c0a0cb0..0000000 --- a/src/test/java/bugreports/snm_20/SNMReport20.java +++ /dev/null @@ -1,381 +0,0 @@ -package bugreports.snm_20; - -import net.sharksystem.CountsReceivedMessagesListener; -import net.sharksystem.SharkException; -import net.sharksystem.asap.*; -import net.sharksystem.asap.apps.TCPServerSocketAcceptor; -import net.sharksystem.utils.streams.StreamPairImpl; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import org.junit.Assert; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; - -import static net.sharksystem.utils.testsupport.TestConstants.URI; -import static net.sharksystem.utils.testsupport.TestConstants.TEST_APP_FORMAT; - -class SNMReport20 { - public static final String TEST_FOLDER = "snmReport20"; - private static final int PORTNUMBER = 6907; - - @Test - public void test2PeersTalkToAlice() throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(TEST_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peers - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPPeerFS alice = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPPeerFS bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - // set up clara - String claraFolder = rootFolder + "/" + TestConstants.CLARA_ID; - ASAPPeerFS clara = new ASAPPeerFS(TestConstants.CLARA_ID, claraFolder, formats); - - CountsReceivedMessagesListener aliceReceivedMessagesListener = new CountsReceivedMessagesListener(); - alice.addASAPMessageReceivedListener(TEST_APP_FORMAT, aliceReceivedMessagesListener); - - ////////////////////////// encounter manager - ASAPEncounterManager aliceEncounterManager = new ASAPEncounterManagerImpl(alice, TestConstants.ALICE_ID); - ASAPEncounterManager bobEncounterManager = new ASAPEncounterManagerImpl(bob, TestConstants.BOB_ID); - ASAPEncounterManager claraEncounterManager = new ASAPEncounterManagerImpl(clara, TestConstants.CLARA_ID); - - ////////////////////////// set up server socket and handle connection requests - int portNumberAlice = TestHelper.getPortNumber(); - - // start system on alice' side - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberAlice, aliceEncounterManager); - - // give it a moment to settle - Thread.sleep(5); - - // send message before connecting - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_1); - clara.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_CLARA_TO_ALICE_1); - - // open connections to Alice - Socket socketBob = new Socket("localhost", portNumberAlice); - Socket socketClara = new Socket("localhost", portNumberAlice); - - // let Bob handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - bobEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketBob.getInputStream(), socketBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - // let Clara handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - claraEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketClara.getInputStream(), socketClara.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - // send messages in an open connection - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_2); - clara.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_CLARA_TO_ALICE_2); - - // give it a moment to run ASAP session - Thread.sleep(3000); - - Assert.assertEquals(4, aliceReceivedMessagesListener.numberOfMessages); - } - - - @Test - public void testOnePeerTalkToAlice() throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(TEST_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peers - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPPeerFS alice = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPPeerFS bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - - CountsReceivedMessagesListener aliceReceivedMessagesListener = new CountsReceivedMessagesListener(); - alice.addASAPMessageReceivedListener(TEST_APP_FORMAT, aliceReceivedMessagesListener); - - ////////////////////////// encounter manager - ASAPEncounterManager aliceEncounterManager = new ASAPEncounterManagerImpl(alice, TestConstants.ALICE_ID); - ASAPEncounterManager bobEncounterManager = new ASAPEncounterManagerImpl(bob, TestConstants.BOB_ID); - - ////////////////////////// set up server socket and handle connection requests - int portNumberAlice = TestHelper.getPortNumber(); - - // start system on alice' side - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberAlice, aliceEncounterManager); - - // give it a moment to settle - Thread.sleep(5); - - // send message before connecting - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_1); - - // open connections to Alice - Socket socketBob = new Socket("localhost", portNumberAlice); - - // let Bob handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - bobEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketBob.getInputStream(), socketBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - // send messages in an open connection - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_2); - - // give it a moment to run ASAP session - Thread.sleep(3000); - - Assert.assertEquals(2, aliceReceivedMessagesListener.numberOfMessages); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // splitted test // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - @Test - public void alice() throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(TEST_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peer - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPPeerFS alice = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - - CountsReceivedMessagesListener aliceReceivedMessagesListener = new CountsReceivedMessagesListener(); - alice.addASAPMessageReceivedListener(TEST_APP_FORMAT, aliceReceivedMessagesListener); - - ////////////////////////// encounter manager - ASAPEncounterManager aliceEncounterManager = new ASAPEncounterManagerImpl(alice, TestConstants.ALICE_ID); - - ////////////////////////// set up server socket and handle connection requests - // start system on alice' side - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(PORTNUMBER, aliceEncounterManager); - - // give it a moment to settle - Thread.sleep(5); - - // give it a moment to run ASAP session - Thread.sleep(60000); - - Assert.assertEquals(4, aliceReceivedMessagesListener.numberOfMessages); - } - - @Test - public void bobAndClara2() throws InterruptedException { - Thread bobThread = new Thread(new Runnable() { - @Override - public void run() { - try { - peerSends2Alice(TestConstants.BOB_ID, - TestConstants.MESSAGE_BOB_TO_ALICE_1, TestConstants.MESSAGE_ALICE_TO_BOB_2); - } catch (IOException | SharkException | InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - Thread claraThread = new Thread(new Runnable() { - @Override - public void run() { - try { - peerSends2Alice(TestConstants.CLARA_ID, - TestConstants.MESSAGE_CLARA_TO_ALICE_1, TestConstants.MESSAGE_CLARA_TO_ALICE_2); - } catch (IOException | SharkException | InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - - bobThread.start(); - claraThread.start(); - - Thread.sleep(3000); - } - - public void peerSends2Alice(String peerID, byte[] msg1, byte[] msg2) throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(TEST_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peer - String peerFolder = rootFolder + "/" + peerID; - ASAPPeerFS bob = new ASAPPeerFS(peerID, peerFolder, formats); - - ////////////////////////// encounter manager - ASAPEncounterManager peerEncounterManager = new ASAPEncounterManagerImpl(bob, peerID); - - ////////////////////////// set up server socket and handle connection requests - bob.sendASAPMessage(TEST_APP_FORMAT, URI, msg1); - - // open connections to Alice - Socket socket2Alice = new Socket("localhost", PORTNUMBER); - - // let encounter manager handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println(">>>>>>>>>>>>>>>>>>>>>> " + peerID + " 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - peerEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socket2Alice.getInputStream(), socket2Alice.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> " + peerID + " 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - Thread.sleep(1000); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> " + peerID + " SENDING 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - bob.sendASAPMessage(TEST_APP_FORMAT, URI, msg2); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> " + peerID + " SENDING 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - - // give it a moment to run ASAP session - Thread.sleep(3000); - } - - @Test - public void bobAndClara() throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(TEST_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peers - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPPeerFS bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - // set up clara - String claraFolder = rootFolder + "/" + TestConstants.CLARA_ID; - ASAPPeerFS clara = new ASAPPeerFS(TestConstants.CLARA_ID, claraFolder, formats); - - ////////////////////////// encounter manager - ASAPEncounterManager bobEncounterManager = new ASAPEncounterManagerImpl(bob, TestConstants.BOB_ID); - ASAPEncounterManager claraEncounterManager = new ASAPEncounterManagerImpl(clara, TestConstants.CLARA_ID); - - ////////////////////////// set up server socket and handle connection requests - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_1); - clara.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_CLARA_TO_ALICE_1); - - // open connections to Alice - Socket socketBob = new Socket("localhost", PORTNUMBER); - Socket socketClara = new Socket("localhost", PORTNUMBER); - - // let Bob handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println(">>>>>>>>>>>>>>>>>>>>>> BOB 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - bobEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketBob.getInputStream(), socketBob.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> BOB 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - // let Clara handle connection to alice - new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println(">>>>>>>>>>>>>>>>>>>>>> CLARA 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - claraEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socketClara.getInputStream(), socketClara.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> CLARA 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).start(); - - Thread.sleep(1000); - // send messages in an open connection - new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println(">>>>>>>>>>>>>>>>>>>>>> BOB SENDING 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - bob.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_BOB_TO_ALICE_2); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> BOB SENDING 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - - } catch (ASAPException e) { - throw new RuntimeException(e); - } - } - }).start(); - new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println(">>>>>>>>>>>>>>>>>>>>>> CLARA SENDING 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - clara.sendASAPMessage(TEST_APP_FORMAT, URI, TestConstants.MESSAGE_CLARA_TO_ALICE_2); - System.out.println(">>>>>>>>>>>>>>>>>>>>>> CLARA SENDING 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - } catch (ASAPException e) { - throw new RuntimeException(e); - } - } - }).start(); - - // give it a moment to run ASAP session - Thread.sleep(3000); - } -} diff --git a/src/test/java/howto/ConnectPeers.java b/src/test/java/howto/ConnectPeers.java deleted file mode 100644 index b011e83..0000000 --- a/src/test/java/howto/ConnectPeers.java +++ /dev/null @@ -1,216 +0,0 @@ -package howto; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.*; -import net.sharksystem.asap.apps.TCPServerSocketAcceptor; -import net.sharksystem.utils.Log; -import net.sharksystem.utils.streams.StreamPair; -import net.sharksystem.utils.streams.StreamPairImpl; -import net.sharksystem.utils.tcp.SocketFactory; -import net.sharksystem.utils.tcp.StreamPairCreatedListener; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import org.junit.Test; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Problem: ASAPPeers can handle a connection. They are not meant to open a connection be their own. That's task of - * another component. Our framework offers an ASAPTestPeerFS which allows setting up an encounter based on a - * local loop (IP 127.0.0.1) TCP connection - * - * Real scenarios need to set up connections between two peers in different processes or most probably - * different engines. You find examples here. - * - * See also https://github.com/SharedKnowledge/ASAPJava/wiki/EncounterManager - * - * @see net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS - */ -public class ConnectPeers { - - private static final String TEST_FOLDER = "ConnectPeers"; - private CharSequence EXAMPLE_APP_FORMAT = "shark/x-connectPeersExample"; - - /** - * A single connection is set up and two peers run an ASAP encounter. It can work in test scenarios. It is not - * a blueprint for a real application though - better use our encounter manager. - * @throws IOException - * @throws ASAPException - * @throws InterruptedException - */ - @Test - public void connectAliceAndBob() throws IOException, ASAPException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(EXAMPLE_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPPeerFS alicePeerFS = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // we only need connection handler capabilities in this scenario - ASAPConnectionHandler alice = alicePeerFS; - - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPConnectionHandler bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - - /* create a TCP connection. What we do here: - We create a just single connection. We need a ServerSocket first and a Socket that connects to. - - A bit more complex but maybe more convenient solution can be found here: - https://github.com/SharedKnowledge/ASAPJava/blob/master/src/main/java/net/sharksystem/asap/apps/testsupport/ASAPTestPeerFS.java - */ - - // get a port number for that test - int portNumber = TestHelper.getPortNumber(); - - ServerSocket serverSocket = new ServerSocket(portNumber); - - /* - now. We need to accept incoming connection but have to create a socket at the same time... - We need threads or a helper class. - */ - SocketFactory socketFactory = new SocketFactory(serverSocket); - Thread socketFactoryThread = new Thread(socketFactory); - socketFactoryThread.start(); - - // create a socket - String addressRemotePeer = "localhost"; // change this in a real scenario - Socket socket = new Socket(addressRemotePeer, portNumber); - - // give server side a moment to connect - Thread.sleep(1); - - // it is an arbitrary choice - Alice takes socket side pairs - alice.handleConnection(socket.getInputStream(), socket.getOutputStream()); - bob.handleConnection(socketFactory.getInputStream(), socketFactory.getOutputStream()); - - // give it some time to run an encounter. - Thread.sleep(5); - } - - @Test - public void connectAliceAndBob_2() throws IOException, ASAPException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(EXAMPLE_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPPeerFS alicePeerFS = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // we only need connection handler capabilities in this scenario - ASAPConnectionHandler alice = alicePeerFS; - - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPConnectionHandler bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - - /* create a TCP connection. What we do here: - We create a just single connection. We need a ServerSocket first and a Socket that connects to. - - A bit more complex but maybe more convenient solution can be found here: - https://github.com/SharedKnowledge/ASAPJava/blob/master/src/main/java/net/sharksystem/asap/apps/testsupport/ASAPTestPeerFS.java - */ - - // get a port number for that test - int portNumber = TestHelper.getPortNumber(); - - /* - now. We need to accept incoming connection but have to create a socket at the same time... - We need threads or a helper class. - */ - StreamPairCreatedListenerImpl aliceStreamPairCreatedListener = new StreamPairCreatedListenerImpl(alice); - SocketFactory socketFactory = new SocketFactory(portNumber, aliceStreamPairCreatedListener); - Thread socketFactoryThread = new Thread(socketFactory); - socketFactoryThread.start(); - - // create a socket - String addressRemotePeer = "localhost"; // change this in a real scenario - Socket socket = new Socket(addressRemotePeer, portNumber); - - // give server side a moment to connect - Thread.sleep(1); - - // it is an arbitrary choice - Alice takes socket side pairs - bob.handleConnection(socket.getInputStream(), socket.getOutputStream()); - - // give it some time to run an encounter. - Thread.sleep(5); - } - - private class StreamPairCreatedListenerImpl implements StreamPairCreatedListener { - private final ASAPConnectionHandler connectionHandler; - - StreamPairCreatedListenerImpl(ASAPConnectionHandler connectionHandler) { - this.connectionHandler = connectionHandler; - } - - @Override - public void streamPairCreated(StreamPair streamPair) { - try { - this.connectionHandler.handleConnection(streamPair.getInputStream(), streamPair.getOutputStream()); - } catch (IOException | ASAPException e) { - Log.writeLog(this, "problems handling connection: " + e.getLocalizedMessage()); - } - } - } - - @Test - public void connectAliceAndBobWithEncounterManager_Preferred() throws IOException, SharkException, InterruptedException { - // supported formats - Collection formats = new ArrayList<>(); - formats.add(EXAMPLE_APP_FORMAT); - - // test folder for this test run - String rootFolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - ////////////////////////// set up peers - // set up alice - String aliceFolder = rootFolder + "/" + TestConstants.ALICE_ID; - ASAPConnectionHandler alice = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - // set up bob - String bobFolder = rootFolder + "/" + TestConstants.BOB_ID; - ASAPConnectionHandler bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats); - - ////////////////////////// encounter manager - ASAPEncounterManager aliceEncounterManager = new ASAPEncounterManagerImpl(alice, TestConstants.ALICE_ID); - ASAPEncounterManager bobEncounterManager = new ASAPEncounterManagerImpl(bob, TestConstants.BOB_ID); - - ////////////////////////// set up server socket and handle connection requests - int portNumberAlice = TestHelper.getPortNumber(); - TCPServerSocketAcceptor aliceTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberAlice, aliceEncounterManager); - - int portNumberBob = TestHelper.getPortNumber(); - TCPServerSocketAcceptor bobTcpServerSocketAcceptor = - new TCPServerSocketAcceptor(portNumberBob, bobEncounterManager); - - // give it a moment to settle - Thread.sleep(5); - - // now, both side wit for connection establishment. Example - - // open connection to Bob - Socket socket = new Socket("localhost", portNumberBob); - - // let Alice handle it - aliceEncounterManager.handleEncounter( - StreamPairImpl.getStreamPair(socket.getInputStream(), socket.getOutputStream()), - ASAPEncounterConnectionType.INTERNET); - - // give it a moment to run ASAP session - Thread.sleep(5); - - // There is just one peer in a real app. - } -} diff --git a/src/test/java/junit5Tests/release_1/MultipleEncounterTests.java b/src/test/java/junit5Tests/release_1/MultipleEncounterTests.java deleted file mode 100644 index 9bef58f..0000000 --- a/src/test/java/junit5Tests/release_1/MultipleEncounterTests.java +++ /dev/null @@ -1,310 +0,0 @@ -package junit5Tests.release_1; - -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPPeer; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.asap.mockAndTemplates.ASAPMessageReceivedListenerExample; -import net.sharksystem.asap.mockAndTemplates.TestUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - -/** - * @author Rankhole, thsc42 - */ -public class MultipleEncounterTests { - private static final String TEST_FOLDER = "MultipleEncounterTests"; - public static final String ANIMAL_URI = "animal"; - public static final String WATER_URI = "water"; - public static final String ICE_CREAM_URI = "ice_cream"; - - public static final String TIGER_URI = "tiger"; - public static final String ELEPHANT_URI = "elephant"; - public static final String HELLO_URI = "hello"; - - public static final String ALICE_URI_1 = "aliceUri1"; - public static final String ALICE_URI_2 = "aliceUri2"; - public static final String ALICE_URI_3 = "aliceUri3"; - public static final String ALICE_URI_4 = "aliceUri4"; - - public static final String BOB_URI_1 = "bobUri1"; - public static final String BOB_URI_2 = "bobUri2"; - public static final String BOB_URI_3 = "bobUri3"; - public static final String BOB_URI_4 = "bobUri4"; - - private static final String EXAMPLE_APP_FORMAT = "exampleAppFormat"; - - private Collection formats; - private static final int PORT = 7777; - private static int port = 0; - - @BeforeAll - public static void removePreviousTestFolder() { - FSUtils.removeFolder(TestConstants.ROOT_DIRECTORY + TEST_FOLDER); - } - - private ASAPTestPeerFS aliceTestPeer, bobTestPeer, claraTestPeer; - - @BeforeEach - public void setUp() throws IOException, ASAPException { - // create a new folder for each test - avoids conflicts when removal does not work due to race condition - String rootfolder = TestHelper.getFullTempFolderName(TEST_FOLDER, true); - - formats = new ArrayList<>(); - formats.add(EXAMPLE_APP_FORMAT); - - this.aliceTestPeer = new ASAPTestPeerFS( - TestConstants.ALICE_ID, rootfolder + "/" + TestConstants.ALICE_NAME, formats); - this.bobTestPeer = new ASAPTestPeerFS( - TestConstants.BOB_ID, rootfolder + "/" + TestConstants.BOB_NAME, formats); - this.claraTestPeer = new ASAPTestPeerFS( - TestConstants.CLARA_ID, rootfolder + "/" + TestConstants.CLARA_NAME, formats); - } - - @Test - public void singleEncounter_differentURIs() throws InterruptedException, IOException, ASAPException { - String uriAlice = ANIMAL_URI; - String uriBob = WATER_URI; - - simpleEncounterWithMessageExchange(uriAlice, uriBob); - - // chunks should be created for each send message - // this will only be checked on single encounter tests, as in further tests this gets more and more tedious to do - Assertions.assertTrue(aliceTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriAlice, 0)); - Assertions.assertTrue(bobTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriBob, 0)); - Assertions.assertTrue(aliceTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriBob, 1)); - Assertions.assertTrue(bobTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriAlice, 1)); - - // each message should have created a new era, so there should be a meta and content file in each subfolder - Assertions.assertTrue( - this.senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, uriBob, 0)); - Assertions.assertTrue( - this.senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, uriAlice, 0)); - } - - @Test - public void singleEncounter_sameURIs() throws InterruptedException, IOException, ASAPException { - String uriAlice = ANIMAL_URI; - String uriBob = ANIMAL_URI; - - simpleEncounterWithMessageExchange(uriAlice, uriBob); - - // chunks should be created for each send message - // this will only be checked on single encounter tests, as in further tests this gets more and more tedious to do - Assertions.assertTrue(aliceTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriAlice, 0)); - Assertions.assertTrue(bobTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriBob, 0)); - Assertions.assertTrue(aliceTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriBob, 1)); - Assertions.assertTrue(bobTestPeer.getASAPStorage(EXAMPLE_APP_FORMAT).getChunkStorage().existsChunk(uriAlice, 1)); - - - // each message should have created a new era, so there should be a meta and content file in each subfolder - Assertions.assertTrue( - this.senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, uriBob, 0)); - } - - @Test - public void multiEncounter_sameURIs() throws InterruptedException, IOException, ASAPException { - String uri = ICE_CREAM_URI; - int numberOfLoops = 4; - for(int i = 0; i < numberOfLoops; i++) { - simpleEncounterWithMessageExchange(uri, uri); - } - - for(int era = 0; era < numberOfLoops; era++) { - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, uri, era)); - - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, uri, era)); - } - } - - @Test - public void multiEncounter_partiallyDifferentURIs() throws InterruptedException, IOException, ASAPException { - // sending different uris back and forth now breaks it - simpleEncounterWithMessageExchange(TIGER_URI, ICE_CREAM_URI, 1); - simpleEncounterWithMessageExchange(ICE_CREAM_URI, ELEPHANT_URI, 2); - simpleEncounterWithMessageExchange(HELLO_URI, ICE_CREAM_URI, 3); - simpleEncounterWithMessageExchange(ICE_CREAM_URI, HELLO_URI, 4); - - int era = 0; - // encounter #1: Alice (TIGER_URI) < - > Bob (ICE_CREAM) - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ICE_CREAM_URI, era)); - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, TIGER_URI, era)); - - era++; - // encounter #2: Alice (ICE_CREAM) < - > Bob (ELEPHANT_URI) - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ELEPHANT_URI, era)); - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ICE_CREAM_URI, era)); - - era++; - // encounter #3: Alice (HELLO_URI) < - > Bob (ICE_CREAM) - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ICE_CREAM_URI, era)); - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, HELLO_URI, era)); - - era++; - // encounter #4: Alice (ICE_CREAM) < - > Bob (HELLO_URI) - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, HELLO_URI, era)); - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ICE_CREAM_URI, era)); - } - - @Test - public void multiEncounter_completelyDifferentURIs() throws InterruptedException, IOException, ASAPException { - - int numberEncounter = 4; - String[][] exchangedUris = new String[numberEncounter][]; - - int aliceIndex = 0; // take index 0 for alice uri - int bobIndex = 1; // take index 0 for bob uri - - // define what to exchange in each encounter - exchangedUris[0] = new String[] {ALICE_URI_1, BOB_URI_1}; // alice at index 0 && bob at index 1 - exchangedUris[1] = new String[] {ALICE_URI_2, BOB_URI_2}; - exchangedUris[2] = new String[] {ALICE_URI_3, BOB_URI_3}; - exchangedUris[3] = new String[] {ALICE_URI_4, BOB_URI_4}; - - // run encounter - for(int i = 0; i < numberEncounter; i++) { - simpleEncounterWithMessageExchange(exchangedUris[i][aliceIndex], exchangedUris[i][bobIndex], i); - } - - // test - for(int era = 0; era < numberEncounter; era++) { - System.out.print("check era #" + era); - // Alice got Bob's uri - Assertions.assertTrue( - senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, - TestConstants.BOB_ID, exchangedUris[era][bobIndex], era)); - // Bob received Alice's uri - Assertions.assertTrue( - senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, - TestConstants.ALICE_ID, exchangedUris[era][aliceIndex], era)); - } - } - - @Test - public void multipleEncounterRouting() throws IOException, ASAPException, InterruptedException { - String alice2claraURI = "HelloToClara"; - String clara2aliceURI = "FromClara"; - int enounterCounter = 0; - simpleEncounterWithMessageExchange(TIGER_URI, ANIMAL_URI, enounterCounter++); - simpleEncounterWithMessageExchange(ANIMAL_URI, ELEPHANT_URI, enounterCounter++); - simpleEncounterWithMessageExchange(HELLO_URI, ANIMAL_URI, enounterCounter++); - simpleEncounterWithMessageExchange(ANIMAL_URI, HELLO_URI, enounterCounter++); - - // as always, alice and bob should have received all four messages - Assertions.assertTrue(senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ANIMAL_URI, 0)); - Assertions.assertTrue(senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ELEPHANT_URI, 1)); - Assertions.assertTrue(senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ANIMAL_URI, 2)); - Assertions.assertTrue(senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, HELLO_URI, 3)); - - Assertions.assertTrue(senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, TIGER_URI, 0)); - Assertions.assertTrue(senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ANIMAL_URI, 1)); - Assertions.assertTrue(senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, HELLO_URI, 2)); - Assertions.assertTrue(senderEraShouldExist(bobTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ANIMAL_URI, 3)); - - // check if routing is allowed (should be by default) - Assertions.assertTrue(aliceTestPeer.isASAPRoutingAllowed(EXAMPLE_APP_FORMAT)); - // exchange between alice and clara - simpleEncounterWithMessageExchange(aliceTestPeer, claraTestPeer, alice2claraURI, clara2aliceURI, enounterCounter++); - // Alice should have received message from Clara - Assertions.assertTrue(senderEraShouldExist(aliceTestPeer, EXAMPLE_APP_FORMAT, TestConstants.CLARA_ID, clara2aliceURI, 0)); - // and vice versa - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, alice2claraURI, 4)); - - // all messages from Alice should have arrived at Clara - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, TIGER_URI, 0)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ANIMAL_URI, 1)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, HELLO_URI, 2)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.ALICE_ID, ANIMAL_URI, 3)); - - // all messages from Bob, which Alice had previously received, should have arrived at Clara - // BUG: only the first message is routed - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ANIMAL_URI, 0)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ELEPHANT_URI, 1)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, ANIMAL_URI, 2)); - Assertions.assertTrue(senderEraShouldExist(claraTestPeer, EXAMPLE_APP_FORMAT, TestConstants.BOB_ID, HELLO_URI, 3)); - } - - public void simpleEncounterWithMessageExchange(String uriAlice, String uriBob) - throws IOException, ASAPException, InterruptedException { - this.simpleEncounterWithMessageExchange(uriAlice, uriBob, 0); - } - - // send messages with given uri, starts and then stops the encounter - // message content is irrelevant, we don't test for it - public void simpleEncounterWithMessageExchange(String uriAlice, String uriBob, int encounterNumber) - throws IOException, ASAPException, InterruptedException { - - simpleEncounterWithMessageExchange(aliceTestPeer, bobTestPeer, uriAlice, uriBob, encounterNumber); - } - - // send messages with given uri, starts and then stops the encounter - // message content is irrelevant, we don't test for it - public void simpleEncounterWithMessageExchange(ASAPTestPeerFS peerA, ASAPTestPeerFS peerB, String uriAlice, String uriBob, int encounterNumber) - throws IOException, ASAPException, InterruptedException { - - // simulate ASAP first encounter with full ASAP protocol stack and engines - System.out.println("+++++++++++++++++++ encounter #" + encounterNumber + " starts soon ++++++++++++++++++++"); - Thread.sleep(50); - - // setup message received listener - this should be replaced with your code - you implement a listener. - ASAPMessageReceivedListenerExample aliceMessageReceivedListenerExample = - new ASAPMessageReceivedListenerExample(); - - peerA.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, aliceMessageReceivedListenerExample); - - // example - this should be produced by your application - byte[] serializedData = TestUtils.serializeExample(42, "from alice", true); - - peerA.sendASAPMessage(EXAMPLE_APP_FORMAT, uriAlice, serializedData); - - ///////////////// BOB ////////////////////////////////////////////////////////////// - - // this should be replaced with your code - you must implement a listener. - ASAPMessageReceivedListenerExample asapMessageReceivedListenerExample = - new ASAPMessageReceivedListenerExample(); - - // register your listener (or that mock) with asap connection mock - peerB.addASAPMessageReceivedListener(EXAMPLE_APP_FORMAT, asapMessageReceivedListenerExample); - - // bob writes something - peerB.sendASAPMessage(EXAMPLE_APP_FORMAT, uriBob, - TestUtils.serializeExample(43, "from bob", false)); - peerB.sendASAPMessage(EXAMPLE_APP_FORMAT, uriBob, - TestUtils.serializeExample(44, "from bob again", false)); - - // give your app a moment to process - Thread.sleep(500); - // start actual encounter - peerA.startEncounter(TestHelper.getPortNumber(), peerB); - - // give your app a moment to process - Thread.sleep(1000); - // stop encounter - peerB.stopEncounter(peerA); - // give your app a moment to process - Thread.sleep(1000); - } - - public boolean senderEraShouldExist(ASAPPeer peer, String format, String sender, String uri, int era) - throws IOException, ASAPException { - return peer.getASAPStorage(format).getExistingIncomingStorage(sender).getChunkStorage().existsChunk(uri, era); - } -} diff --git a/src/test/java/junit5Tests/release_1/net/sharksystem/asap/LSANEncounterManagerAdminTests.java b/src/test/java/junit5Tests/release_1/net/sharksystem/asap/LSANEncounterManagerAdminTests.java deleted file mode 100644 index 30e66ac..0000000 --- a/src/test/java/junit5Tests/release_1/net/sharksystem/asap/LSANEncounterManagerAdminTests.java +++ /dev/null @@ -1,156 +0,0 @@ -package junit5Tests.release_1.net.sharksystem.asap; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.*; -import net.sharksystem.asap.apps.TCPServerSocketAcceptor; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.testhelper.ASAPTesthelper; -import net.sharksystem.utils.streams.StreamPair; -import net.sharksystem.utils.streams.StreamPairImpl; -import net.sharksystem.utils.testsupport.ASAPMessageReceivedStorage; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.Socket; -import java.util.HashSet; -import java.util.Set; - -public class LSANEncounterManagerAdminTests { - public static final String TEST_CLASS_ROOTFOLDER = TestConstants.ROOT_DIRECTORY + "encounterAdmin/"; - public static final String ALICE_ROOTFOLDER = TEST_CLASS_ROOTFOLDER + TestConstants.ALICE_NAME; - public static final String BOB_ROOTFOLDER = TEST_CLASS_ROOTFOLDER + TestConstants.BOB_NAME; - - public Set supportedFormats; - private ASAPEncounterManagerImpl aliceEncounterManager, bobEncounterManager; - private ASAPPeerFS aliceASAPPeerFS, bobASAPPeerFS; - - ASAPMessageReceivedStorage aliceASAPMessageReceivedListener, bobASAPMessageReceivedListener; - - @BeforeEach - public void setUp() throws IOException, SharkException { - this.supportedFormats = new HashSet<>(); - this.supportedFormats.add(TestConstants.TEST_APP_FORMAT); - - String aliceFolder = ASAPTesthelper.getUniqueFolderName(ALICE_ROOTFOLDER.toString()); - String bobFolder = ASAPTesthelper.getUniqueFolderName(BOB_ROOTFOLDER.toString()); - TestHelper.incrementTestNumber(); - - //////////////////////////////// setup Alice - TestHelper.removeFolder(aliceFolder); // clean folder from previous tests - TestHelper.removeFolder(bobFolder); // clean folder from previous tests - - aliceASAPPeerFS = new ASAPTestPeerFS(TestConstants.ALICE_ID, aliceFolder, this.supportedFormats); - aliceASAPMessageReceivedListener = new ASAPMessageReceivedStorage(); - aliceASAPPeerFS.addASAPMessageReceivedListener(TestConstants.TEST_APP_FORMAT, aliceASAPMessageReceivedListener); - - bobASAPPeerFS = new ASAPTestPeerFS(TestConstants.BOB_ID, bobFolder, this.supportedFormats); - bobASAPMessageReceivedListener = new ASAPMessageReceivedStorage(); - bobASAPPeerFS.addASAPMessageReceivedListener(TestConstants.TEST_APP_FORMAT, bobASAPMessageReceivedListener); - - aliceEncounterManager = new ASAPEncounterManagerImpl(aliceASAPPeerFS, TestConstants.ALICE_ID); - bobEncounterManager = new ASAPEncounterManagerImpl(bobASAPPeerFS, TestConstants.BOB_ID); - } - - private void runAliceBobEncounter() throws IOException, InterruptedException { - int port = TestHelper.getPortNumber(); - System.out.println(">>>>>>>>>>>>> START RUNNING ENCOUNTER ALICE <-> BOB (initiator) on port " + port); - // open port on alice side - and run it through her encounter manager - new TCPServerSocketAcceptor(port, aliceEncounterManager); - // connect from bob side - Socket connect2Alice = new Socket("localhost", port); - StreamPair bob2AliceStreamPair = StreamPairImpl.getStreamPair(connect2Alice.getInputStream(), connect2Alice.getOutputStream(), - null, TestConstants.ALICE_ID); - - // Alice will handle - bobEncounterManager.handleEncounter(bob2AliceStreamPair, ASAPEncounterConnectionType.INTERNET); - Thread.sleep(200); - } - - @Test - public void testOneMessageA2B() throws InterruptedException, IOException, ASAPException { - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_1); - this.runAliceBobEncounter(); - Assert.assertEquals(1, bobASAPMessageReceivedListener.getNumberReceivedMessages()); - - } - - @Test - public void testOneMessageA2BFailsBecauseBothBlocked() throws InterruptedException, IOException, ASAPException { - int port = TestHelper.getPortNumber(); - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_1); - aliceEncounterManager.addToDenyList(TestConstants.BOB_ID); - bobEncounterManager.addToDenyList(TestConstants.ALICE_ID); - - this.runAliceBobEncounter(); - - Assert.assertEquals(0, bobASAPMessageReceivedListener.getNumberReceivedMessages()); - } - - @Test - public void testOneMessageA2BFailsBecauseOneBlocked() throws InterruptedException, IOException, ASAPException { - int port = TestHelper.getPortNumber(); - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_1); - aliceEncounterManager.addToDenyList(TestConstants.BOB_ID); - - this.runAliceBobEncounter(); - - Assert.assertEquals(0, bobASAPMessageReceivedListener.getNumberReceivedMessages()); - } - - @Test - public void testAliceSendsTwoMessages() throws InterruptedException, IOException, ASAPException { - // send message when offline - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_1); - this.runAliceBobEncounter(); - // send message when online - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_2); - Thread.sleep(200); - Assert.assertEquals(2, bobASAPMessageReceivedListener.getNumberReceivedMessages()); - - } - - @Test - public void testAliceSendsOneMessageConnectionKilled() throws InterruptedException, IOException, ASAPException { - // send message when offline - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_1); - this.runAliceBobEncounter(); - - // kill connection via encounter manager - aliceEncounterManager.closeEncounter(TestConstants.BOB_ID); - // try to send another message - aliceASAPPeerFS.sendASAPMessage(TestConstants.TEST_APP_FORMAT, TestConstants.URI, TestConstants.MESSAGE_2); - Thread.sleep(200); - // second message should not reach Bob - connection closed. It would get delivered after a reconnect - Assert.assertEquals(1, bobASAPMessageReceivedListener.getNumberReceivedMessages()); - } - - @Test - public void testPersistDenyList() throws SharkException, IOException, InterruptedException { - String emPeristFolder = TEST_CLASS_ROOTFOLDER + "persistEncManagerTest"; - - ASAPEncounterManagerImpl encounterManager = - new ASAPEncounterManagerImpl(null, null,1, emPeristFolder); - - encounterManager.clearDenyList(); - encounterManager.addToDenyList(TestConstants.ALICE_ID); - - // restore - encounterManager = new ASAPEncounterManagerImpl(null, null,1, emPeristFolder); - - Set denyList = encounterManager.getDenyList(); - Assert.assertEquals(1, denyList.size()); - Assert.assertTrue(denyList.contains(TestConstants.ALICE_ID)); - - // clear - encounterManager.clearDenyList(); -// Thread.sleep(100); - // reload again - encounterManager = new ASAPEncounterManagerImpl(null, null,1, emPeristFolder); - denyList = encounterManager.getDenyList(); - Assert.assertEquals(0, denyList.size()); - } -} \ No newline at end of file diff --git a/src/test/java/net/sharksystem/CommandlineTests.java b/src/test/java/net/sharksystem/CommandlineTests.java deleted file mode 100644 index d9b7aa6..0000000 --- a/src/test/java/net/sharksystem/CommandlineTests.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.sharksystem; - -import net.sharksystem.utils.Commandline; -import org.junit.Assert; -import org.junit.Test; - -import java.util.HashMap; - -public class CommandlineTests { - @Test - public void test1() { - String key0 = "-help"; - String key1 = "-o"; - String value1 = "xyz"; - String[] args = new String[] {key0, key1, value1}; - HashMap argsMap = Commandline.parametersToMap(args, false, "helpmessage"); - - Assert.assertEquals(2, argsMap.size()); - - // 0 - Assert.assertNull(argsMap.get(key0)); - // 1 - String valueInMap = argsMap.get(key1); - Assert.assertTrue(valueInMap.equalsIgnoreCase(value1)); - } -} diff --git a/src/test/java/net/sharksystem/CountsReceivedMessagesListener.java b/src/test/java/net/sharksystem/CountsReceivedMessagesListener.java deleted file mode 100644 index a1dd552..0000000 --- a/src/test/java/net/sharksystem/CountsReceivedMessagesListener.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sharksystem; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessageReceivedListener; -import net.sharksystem.asap.ASAPMessages; - -import java.io.IOException; -import java.util.List; - -public class CountsReceivedMessagesListener implements ASAPMessageReceivedListener { - private final String peerName; - public int numberOfMessages = 0; - - public CountsReceivedMessagesListener(String peerName) { - this.peerName = peerName; - } - - public CountsReceivedMessagesListener() { - this(null); - } - - @Override - public void asapMessagesReceived(ASAPMessages messages, - String senderE2E, // E2E part - List asapHopsList) throws IOException { - CharSequence format = messages.getFormat(); - CharSequence uri = messages.getURI(); - if (peerName != null) { - System.out.print(peerName); - } - - this.numberOfMessages += messages.size(); - } -} \ No newline at end of file diff --git a/src/test/java/net/sharksystem/TodoTests.java b/src/test/java/net/sharksystem/TodoTests.java deleted file mode 100644 index bfdde85..0000000 --- a/src/test/java/net/sharksystem/TodoTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sharksystem; - - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import net.sharksystem.asap.engine.Point2PointTests; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - Point2PointTests.class -}) -public class TodoTests { -} diff --git a/src/test/java/net/sharksystem/V1TestSuite.java b/src/test/java/net/sharksystem/V1TestSuite.java deleted file mode 100644 index 3905a61..0000000 --- a/src/test/java/net/sharksystem/V1TestSuite.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.sharksystem; - -import howto.ConnectPeers; -import net.sharksystem.asap.crypto.CryptoUsage; -import net.sharksystem.asap.engine.*; -import net.sharksystem.asap.helper.HelperTester; -import net.sharksystem.asap.peer.Point2Point2Test2; -import net.sharksystem.asap.peer.TransientMessages; -import net.sharksystem.asap.protocol.PDUTests; -import net.sharksystem.asap.serialization.SerializationTests; -import net.sharksystem.asap.storage.StorageTests; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - SerializationTests.class, - BasisMethodsTests.class, - UsageExamples.class, - CreateNewChannelFromOutsideTest.class, - PDUTests.class, - CryptoTests.class, - StorageTests.class, - LongerMessages.class, - CryptoUsage.class, - HelperTester.class, - MultihopTests.class, - CommandlineTests.class, - TransientMessages.class, - Point2Point2Test2.class, - ConnectPeers.class, // - //MultipleEncounterTests.class - //E2EStreamPairLinkTestVersion2.class TODO - -}) -public class V1TestSuite { - -} diff --git a/src/test/java/net/sharksystem/asap/appTests/Reenactment.java b/src/test/java/net/sharksystem/asap/appTests/Reenactment.java deleted file mode 100644 index 2705a79..0000000 --- a/src/test/java/net/sharksystem/asap/appTests/Reenactment.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.sharksystem.asap.appTests; - -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.asap.ASAPException; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - -public class Reenactment { - public static final String ALICE_ROOT_FOLDER = "reenact/Alice"; - public static final String ALICE_APP_FOLDER = ALICE_ROOT_FOLDER + "/appFolder"; - public static final String BOB_ROOT_FOLDER = "reenact/Bob"; - public static final String BOB_APP_FOLDER = BOB_ROOT_FOLDER + "/appFolder"; - public static final String ALICE = "Alice"; - public static final String BOB = "Bob"; - - - @Test - public void reenact2021_01_05() throws IOException, ASAPException, InterruptedException { - String format = "application/x-BluetoothSchach"; - String uri1 = "bluetoothschach://"; - String uri2 = "bluetoothschach://3979"; - String oneSign = "X"; - String message = "message B -> A"; - - Collection formats = new ArrayList<>(); - formats.add(format); - - ///////////////// ALICE ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(ALICE, formats); - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(BOB, formats); - - aliceSimplePeer.sendASAPMessage(format, uri1, oneSign.getBytes()); - - bobSimplePeer.sendASAPMessage(format, uri2, message.getBytes()); - - aliceSimplePeer.startEncounter(7777, bobSimplePeer); - // give your app a moment to process - Thread.sleep(1000); - // stop encounter - bobSimplePeer.stopEncounter(aliceSimplePeer); - // give your app a moment to process - Thread.sleep(1000); - } -} diff --git a/src/test/java/net/sharksystem/asap/crypto/CryptoUsage.java b/src/test/java/net/sharksystem/asap/crypto/CryptoUsage.java deleted file mode 100644 index 08c4108..0000000 --- a/src/test/java/net/sharksystem/asap/crypto/CryptoUsage.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.sharksystem.asap.crypto; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.security.NoSuchAlgorithmException; - -import static net.sharksystem.utils.testsupport.TestConstants.ALICE_ID; -import static net.sharksystem.utils.testsupport.TestConstants.BOB_ID; - -public class CryptoUsage { - private InMemoASAPKeyStore aliceKeyStorage; - private InMemoASAPKeyStore bobKeyStorage; - - @Before - public void setupASAPKeyStores() throws ASAPSecurityException { - this.aliceKeyStorage = new InMemoASAPKeyStore(ALICE_ID); - this.bobKeyStorage = new InMemoASAPKeyStore(BOB_ID); - - // simulate key exchange - this.aliceKeyStorage.addKeyPair(BOB_ID, bobKeyStorage.getKeyPair()); - this.bobKeyStorage.addKeyPair(ALICE_ID, aliceKeyStorage.getKeyPair()); - } - - @Test - public void printFingerprint() throws ASAPSecurityException, NoSuchAlgorithmException { - System.out.println(ASAPCryptoAlgorithms.getFingerprint(aliceKeyStorage.getPublicKey())); - } - - - @Test - public void signVerifyUsage() throws ASAPSecurityException { - String messageString = "From Alice signed"; - // produce bytes - byte[] messageBytes = messageString.getBytes(); - // alice signs a message - byte[] signedMessage = ASAPCryptoAlgorithms.sign(messageBytes, aliceKeyStorage); - - // verify - Assert.assertTrue(ASAPCryptoAlgorithms.verify(messageBytes, signedMessage, ALICE_ID, bobKeyStorage)); - } - - @Test - public void encryptedPackageUsageExample() throws IOException, ASAPException { - String messageString = "From Alice, encrypted for Bob"; - // produce bytes - byte[] messageBytes = messageString.getBytes(); - - // produce encryption package: encrypt with new session key, encrypt session key with receivers public key - byte[] encryptedMessagePackageBytes = ASAPCryptoAlgorithms.produceEncryptedMessagePackage( - messageBytes, // message that is encrypted - BOB_ID, // recipient id - aliceKeyStorage // key store sender - ); - - // package is sent e.g. with ASAP - byte[] receivedEncryptedPackageBytes = encryptedMessagePackageBytes; - - // receiver creates package from byte[] - will fail if we are not recipient - ASAPCryptoAlgorithms.EncryptedMessagePackage receivedEncryptedPackage = - ASAPCryptoAlgorithms.parseEncryptedMessagePackage(receivedEncryptedPackageBytes); - - // decrypt message - byte[] receivedMessageBytes = - ASAPCryptoAlgorithms.decryptPackage(receivedEncryptedPackage, bobKeyStorage); - - // must be the same - Assert.assertArrayEquals(messageBytes, receivedMessageBytes); - } -} diff --git a/src/test/java/net/sharksystem/asap/crypto/PersistInMemoKeystore.java b/src/test/java/net/sharksystem/asap/crypto/PersistInMemoKeystore.java deleted file mode 100644 index 4ae5ad7..0000000 --- a/src/test/java/net/sharksystem/asap/crypto/PersistInMemoKeystore.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.sharksystem.asap.crypto; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import org.junit.Test; - -import java.io.IOException; - -import static net.sharksystem.utils.testsupport.TestConstants.ALICE_ID; - -public class PersistInMemoKeystore { - /** - * It is not really a good idea to implement a serialization like this. It is extremely - * vulnerable... But is makes testing a bit easier. - */ - @Test - public void writeAndRestore() throws ASAPException, IOException { - InMemoASAPKeyStore imKeystore = new InMemoASAPKeyStore("TestPeer"); - imKeystore.generateKeyPair(); - - byte[] memento = imKeystore.getMemento(); - imKeystore.restoreMemento(memento); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/BasisCryptoTests.java b/src/test/java/net/sharksystem/asap/engine/BasisCryptoTests.java deleted file mode 100644 index 19f9352..0000000 --- a/src/test/java/net/sharksystem/asap/engine/BasisCryptoTests.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.crypto.ASAPCryptoAlgorithms; -import net.sharksystem.asap.crypto.InMemoASAPKeyStore; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; - -public class BasisCryptoTests { - public static final String ALICE_ID = "Alice"; - public static final String BOB_ID = "Bob"; - - @Test - public void publicKeyExportImport() throws ASAPSecurityException, IOException, InvalidKeySpecException, NoSuchAlgorithmException { - InMemoASAPKeyStore aliceStorage = new InMemoASAPKeyStore(ALICE_ID); - // a message - String msg = "Hi Bob"; - - // convert to bytes - byte[] msgBytes = msg.getBytes(); - - // sign a message - with Alice' private key - byte[] signatureBytes = ASAPCryptoAlgorithms.sign(msgBytes, aliceStorage); - - // Alice could now send message with signature to bob - we are in a test, nothing to do here. - - // Bob need to know Alice' public key to verify - simulate transfer - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - aliceStorage.writePublicKey(baos); - - InMemoASAPKeyStore bobStorage = new InMemoASAPKeyStore(BOB_ID); - // store Alice' public key with Bob - bobStorage.readPublicKey(ALICE_ID, new ByteArrayInputStream(baos.toByteArray())); - - Assert.assertTrue(ASAPCryptoAlgorithms.verify(msgBytes, signatureBytes, ALICE_ID, bobStorage)); - } - - -} diff --git a/src/test/java/net/sharksystem/asap/engine/BasisMethodsTests.java b/src/test/java/net/sharksystem/asap/engine/BasisMethodsTests.java deleted file mode 100644 index 9b27849..0000000 --- a/src/test/java/net/sharksystem/asap/engine/BasisMethodsTests.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -public class BasisMethodsTests { - - @Test - public void asapID() throws InterruptedException { - for (int i = 0; i < 10; i++) { - System.out.println(ASAP.createUniqueID()); - Thread.sleep(2); - } - } - - @Test - public void bitMasks() throws IOException, ASAPException { - int flags = 0x0000BA98; - System.out.print("1: "); - ASAPSerialization.printBits(flags); - System.out.print("\n"); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - byte flagBytes = ASAPSerialization.getByteFromInt(flags, 0); - ASAPSerialization.writeByteParameter(flagBytes, os); // mand - flagBytes = ASAPSerialization.getByteFromInt(flags, 1); - ASAPSerialization.writeByteParameter(flagBytes, os); // mand - - ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); - - byte byteLeastSignificant = ASAPSerialization.readByte(is); - byte byteNextByte = ASAPSerialization.readByte(is); - - int retFlags = byteNextByte; - retFlags = retFlags << 8; - System.out.print("2: "); - ASAPSerialization.printBits(retFlags); - System.out.print("\n"); - - // set all random bits to 0 - retFlags = retFlags & 0x0000FF00; - // set all bits in higher byte to zero - not exactly necessary but makes debugging easier - System.out.print("3: "); - ASAPSerialization.printBits(retFlags); - System.out.print("\n"); - - int leastSignificantInt = byteLeastSignificant; - leastSignificantInt = leastSignificantInt & 0x000000FF; - System.out.print("4: "); - ASAPSerialization.printBits(leastSignificantInt); - System.out.print("\n"); - - retFlags = retFlags | leastSignificantInt; - System.out.print("5: "); - ASAPSerialization.printBits(retFlags); - System.out.print("\n"); - - Assert.assertEquals(flags, retFlags); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/ChunkCacheTests.java b/src/test/java/net/sharksystem/asap/engine/ChunkCacheTests.java deleted file mode 100644 index 3d40133..0000000 --- a/src/test/java/net/sharksystem/asap/engine/ChunkCacheTests.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.fs.FSUtils; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; - -public class ChunkCacheTests { - public static final String ALICE_FOLDER = "tests/alice"; - public static final String ALICE = "alice"; - public static final String BOB = "bob"; - public static final String CLARA = "clara"; - public static final String DUMMY_USER = "dummyUser"; - public static final String TEST_URI = "TEST_URI"; - public static final String TEST_FORMAT = "format"; - public static final String TEST_APP = "asapApp"; - private static final String MESSAGE_ONE = "message one"; - private static final String MESSAGE_TWO = "message two"; - private static final String MESSAGE_THREE = "message three"; - private static final String MESSAGE_FOUR = "message four"; - private static final String MESSAGE_FIVE = "message five"; - - @Test - public void chunkTest0() throws IOException, ASAPException { - FSUtils.removeFolder(ALICE_FOLDER); // clean previous version before - ASAPEngine aliceStorage = ASAPEngineFS.getASAPStorage(ALICE, ALICE_FOLDER, TEST_APP); - - String[] message = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; - - aliceStorage.add(TEST_URI, message[0]); - aliceStorage.add(TEST_URI, message[1]); - aliceStorage.add(TEST_URI, message[2]); - aliceStorage.add(TEST_URI, message[3]); - aliceStorage.newEra(); - aliceStorage.add(TEST_URI, message[4]); - aliceStorage.add(TEST_URI, message[5]); - aliceStorage.newEra(); - aliceStorage.add(TEST_URI, message[6]); - aliceStorage.add(TEST_URI, message[7]); - aliceStorage.newEra(); - aliceStorage.add(TEST_URI, message[8]); - aliceStorage.add(TEST_URI, message[9]); - aliceStorage.add(TEST_URI, message[0xA]); - aliceStorage.newEra(); - aliceStorage.add(TEST_URI, message[0xB]); - aliceStorage.add(TEST_URI, message[0xC]); - aliceStorage.add(TEST_URI, message[0xD]); - aliceStorage.newEra(); - aliceStorage.add(TEST_URI, message[0xE]); - aliceStorage.add(TEST_URI, message[0xF]); - - // now get message chain - ASAPMessages chunkChain = aliceStorage.getChunkChain(TEST_URI); - for(int i = 0; i < 0x10; i++) { - Assert.assertTrue(chunkChain.getMessageAsCharSequence(i, true).toString() - .equalsIgnoreCase(message[i])); - } - - // now get message chain - reverse order - chunkChain = aliceStorage.getChunkChain(TEST_URI); - for(int i = 0; i < 0x10; i++) { - Assert.assertTrue(chunkChain.getMessageAsCharSequence(i, false).toString() - .equalsIgnoreCase(message[0xF - i])); - } - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/ChunkPrinter.java b/src/test/java/net/sharksystem/asap/engine/ChunkPrinter.java deleted file mode 100644 index 170613d..0000000 --- a/src/test/java/net/sharksystem/asap/engine/ChunkPrinter.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalChunkFS; -import org.junit.Test; - -/** - * - * @author thsc - */ -public class ChunkPrinter { - - @Test - public void printChunk() throws IOException, ASAPException { - Map m = new HashMap<>(); - m.put(null, "A"); - - m.remove(null); - - String chunkTrunkName = "bob/0/content%3A%2F%2FaliceAndBob.talk"; - - System.out.println("going to print content of chunk " + chunkTrunkName); - - try { - ASAPInternalChunkFS chunk = new ASAPInternalChunkFS(null, chunkTrunkName); - - System.out.println("url: " + chunk.getUri()); - - Iterator messages = chunk.getMessagesAsCharSequence(); - if(messages == null) { - System.out.println("no message iterator"); - return; - } - - int i = 0; - while(messages.hasNext()) { - CharSequence s = messages.next(); - StringBuilder b = new StringBuilder(); - b.append(i); - b.append(": "); - b.append(s); - System.out.println(b.toString()); - } - } - catch(Throwable t) { - System.out.println("failure"); - t.printStackTrace(System.out); - } - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/CreateNewChannelFromOutsideTest.java b/src/test/java/net/sharksystem/asap/engine/CreateNewChannelFromOutsideTest.java deleted file mode 100644 index 6957500..0000000 --- a/src/test/java/net/sharksystem/asap/engine/CreateNewChannelFromOutsideTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.cmdline.TCPStream; -import net.sharksystem.fs.FSUtils; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -public class CreateNewChannelFromOutsideTest { - public static final String ALICE_BOB_CHAT_URL = "content://aliceAndBob.talk"; - public static final String CHAT_FORMAT = "application/x-sn2-makan"; - public static final String ALICE_ROOT_FOLDER = "tests/Alice"; - public static final String ALICE_APP_FOLDER = ALICE_ROOT_FOLDER + "/appFolder"; - public static final String BOB_ROOT_FOLDER = "tests/Bob"; - public static final String BOB_APP_FOLDER = BOB_ROOT_FOLDER + "/appFolder"; - public static final String ALICE = "Alice"; - public static final String BOB = "Bob"; - public static final String ALICE2BOB_MESSAGE = "Hi Bob"; - public static final String ALICE2BOB_MESSAGE2 = "Hi Bob again"; - public static final String BOB2ALICE_MESSAGE = "Hi Alice"; - public static final String BOB2ALICE_MESSAGE2 = "Hi Alice again"; - - private static int portnumber = 7777; - - private int getPortNumber() { - portnumber++; - return portnumber; - } - - @Test - public void openMessageExchange() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - FSUtils.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before - FSUtils.removeFolder(BOB_ROOT_FOLDER); // clean previous version before - - // alice writes a message into chunkStorage - ASAPInternalStorage aliceStorage = - ASAPEngineFS.getASAPStorage(ALICE, ALICE_APP_FOLDER, CHAT_FORMAT); - - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE); - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2); - //aliceStorage.addRecipient(ALICE_BOB_CHAT_URL, BOB); - - // bob does the same - ASAPInternalStorage bobStorage = - ASAPEngineFS.getASAPStorage(BOB, BOB_APP_FOLDER, CHAT_FORMAT); - - // there is only Bobs storage - nothing else. That's important. - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare peers // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPInternalPeer aliceEngine = ASAPInternalPeerFS.createASAPPeer(ALICE_ROOT_FOLDER, null); - ASAPInternalPeer bobEngine = ASAPInternalPeerFS.createASAPPeer(BOB_ROOT_FOLDER, null); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // setup connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - int portNumber = this.getPortNumber(); - // create connections for both sides - TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b"); - TCPStream bobChannel = new TCPStream(portNumber, false, "b2a"); - - aliceChannel.start(); - bobChannel.start(); - - // wait to connect - aliceChannel.waitForConnection(); - bobChannel.waitForConnection(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // run asap connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // run engine as thread - ASAPPeerHandleConnectionThread aliceEngineThread = new ASAPPeerHandleConnectionThread(aliceEngine, - aliceChannel.getInputStream(), aliceChannel.getOutputStream()); - - aliceEngineThread.start(); - - // and better debugging - no new thread - bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream()); - - // wait until communication probably ends - System.out.flush(); - System.err.flush(); - Thread.sleep(2000); - System.out.flush(); - System.err.flush(); - - // close connections: note ASAPEngine does NOT close any connection!! - aliceChannel.close(); - bobChannel.close(); - System.out.flush(); - System.err.flush(); - Thread.sleep(1000); - System.out.flush(); - System.err.flush(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // tests // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // there is a new channel - List channelURIs = bobStorage.getChannelURIs(); - Assert.assertEquals(1, channelURIs.size()); - - // and the one and only is... - Assert.assertEquals(ALICE_BOB_CHAT_URL, channelURIs.get(0)); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/CryptoTests.java b/src/test/java/net/sharksystem/asap/engine/CryptoTests.java deleted file mode 100644 index 3801cc8..0000000 --- a/src/test/java/net/sharksystem/asap/engine/CryptoTests.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.cmdline.ExampleASAPChunkReceivedListener; -import net.sharksystem.asap.cmdline.TCPStream; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -public class CryptoTests { - public static final String WORKING_SUB_DIRECTORY = TestConstants.ROOT_DIRECTORY + "cryptoTests/"; - public static final String ALICE_PEER_NAME = "Alice"; - public static final String BOB_PEER_NAME = "Bob"; - public static final String CLARA_PEER_NAME = "Clara"; - public static final String APPNAME = "encryptedChat"; - public static final String CHAT_TOPIC = "topicA"; - public static final int EXAMPLE_PORT = 7070; - public static final String EXAMPLE_MESSAGE_STRING = "Hi"; - - @Test - public void noExchangeNotSigned() throws IOException, ASAPException, InterruptedException { - FSUtils.removeFolder(WORKING_SUB_DIRECTORY); // clean previous version before - - ///// Prepare Alice - String aliceFolder = WORKING_SUB_DIRECTORY + ALICE_PEER_NAME; - - // ASAPChunkReceivedListener - an example - ExampleASAPChunkReceivedListener aliceChunkListener = new ExampleASAPChunkReceivedListener(aliceFolder); - - // setup alice peer - ASAPInternalPeer alicePeer = ASAPInternalPeerFS.createASAPPeer(ALICE_PEER_NAME, aliceFolder, aliceChunkListener); - - // setup chat on alice peer - ASAPEngine aliceChatEngine = alicePeer.createEngineByFormat(APPNAME); - // false is default but makes test more obvious - aliceChatEngine.getASAPCommunicationControl().setSendEncryptedMessages(false); - aliceChatEngine.getASAPCommunicationControl().setSendSignedMessages(false); - - // create a message - String messageAlice = EXAMPLE_MESSAGE_STRING; - - // transform to bytes - there are more elaborate ways to produce a byte array of course - byte[] messageBytes = messageAlice.getBytes(); - - // write a message - we are still offline - aliceChatEngine.add(CHAT_TOPIC, messageBytes); - - ///// Prepare Bob - String bobFolder = WORKING_SUB_DIRECTORY + BOB_PEER_NAME; - - // ASAPChunkReceivedListener - an example - ExampleASAPChunkReceivedListener bobChunkListener = new ExampleASAPChunkReceivedListener(bobFolder); - - // setup bob peer - ASAPInternalPeer bobPeer = ASAPInternalPeerFS.createASAPPeer(BOB_PEER_NAME, bobFolder, bobChunkListener); - - // setup chat on alice peer - ASAPEngine bobChatEngine = bobPeer.createEngineByFormat(APPNAME); - // bob expects signed and encrypted what Alice not provides - bobChatEngine.getASAPEnginePermissionSettings().setReceivedMessagesMustBeEncrypted(true); - bobChatEngine.getASAPEnginePermissionSettings().setReceivedMessagesMustBeSigned(true); - - /////////////// create a connection - in real apps it is presumably a bluetooth wifi direct etc. connection - // TCPStream is a helper class for connection establishment - TCPStream aliceStream = new TCPStream(EXAMPLE_PORT, true, "alice2bob"); - TCPStream bobStream = new TCPStream(EXAMPLE_PORT, false, "b2a"); - - // start tcp server or client and try to connect - aliceStream.start(); - bobStream.start(); - - // wait until connection is established - aliceStream.waitForConnection(); - bobStream.waitForConnection(); - //////////////// end of connection establishment - a simulation in some way - but real enough. It is real tcp. - - // let both asap peers run an asap session - ASAPPeerHandleConnectionThread aliceThread = new ASAPPeerHandleConnectionThread(alicePeer, - aliceStream.getInputStream(), aliceStream.getOutputStream()); - - // alice is up and running in a thread - aliceThread.start(); - - // run bob in this test thread - bobPeer.handleConnection(bobStream.getInputStream(), bobStream.getOutputStream()); - - // at this point give both asap engines some time to run their asap session - then we check what happened. - Thread.sleep(1000); - - // we assume the asap session was performed - - // bob chunk received listener must have received something - List receivedList = - bobChunkListener.getReceivedList(); - Assert.assertTrue(receivedList.isEmpty()); - - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/LongerMessages.java b/src/test/java/net/sharksystem/asap/engine/LongerMessages.java deleted file mode 100644 index fed1355..0000000 --- a/src/test/java/net/sharksystem/asap/engine/LongerMessages.java +++ /dev/null @@ -1,183 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.utils.ASAPChunkReceivedTester; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.cmdline.TCPStream; -import net.sharksystem.asap.utils.ASAPSerialization; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Iterator; - -import static net.sharksystem.asap.engine.ASAPInternalPeer.DEFAULT_MAX_PROCESSING_TIME; - -public class LongerMessages { - public static final String ALICE_BOB_CHAT_URL = "content://aliceAndBob.talk"; - public static final String CHAT_FORMAT = "application/x-sn2-makan"; - public static String ALICE_ROOT_FOLDER = TestConstants.ROOT_DIRECTORY + "longmessage/Alice"; - public static String ALICE_APP_FOLDER = ALICE_ROOT_FOLDER + "/appFolder"; - public static final String BOB_ROOT_FOLDER = TestConstants.ROOT_DIRECTORY + "longmessage/Bob"; - public static final String BOB_APP_FOLDER = BOB_ROOT_FOLDER + "/appFolder"; - public static final String ALICE = "Alice"; - public static final String BOB = "Bob"; - - - // 200 - public static final String ALICE2BOB_MESSAGE = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; - //public static final String ALICE2BOB_MESSAGE = "Hi Bob"; - //public static final String ALICE2BOB_MESSAGE2 = "HiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgain"; - public static final String ALICE2BOB_MESSAGE2 = "Hi Again"; - - private static int portnumber = 7777; - - private int getPortNumber() { - portnumber++; - return portnumber; - } - - @Test - public void serializeDeserializeTest() throws IOException, ASAPException { - long writeLong = 0x9ABCDEF012345678L; - //long writeLong = 0x9999999999999999L; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeLongParameter(writeLong, baos); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - long readLong = ASAPSerialization.readLongParameter(bais); - - Assert.assertEquals(writeLong, readLong); - } - - @Test - public void longerMessagesAlice2Bob() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - FSUtils.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before - FSUtils.removeFolder(BOB_ROOT_FOLDER); // clean previous version before - - // alice writes a message into chunkStorage - ASAPInternalStorage aliceStorage = ASAPEngineFS.getASAPStorage(ALICE, ALICE_APP_FOLDER, CHAT_FORMAT); - - int aliceInitialEra = aliceStorage.getEra(); - - aliceStorage.createChannel(ALICE_BOB_CHAT_URL, BOB); - - // content changed - next change in topology should increase alice era. - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE); - - // bob does the same - ASAPInternalStorage bobStorage = ASAPEngineFS.getASAPStorage(BOB, BOB_APP_FOLDER, CHAT_FORMAT); - - int bobInitialEra = bobStorage.getEra(); - - bobStorage.createChannel(ALICE_BOB_CHAT_URL, ALICE); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare multi engines // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPChunkReceivedTester aliceListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer aliceEngine = ASAPInternalPeerFS.createASAPPeer( - ALICE, ALICE_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, aliceListener); - - ASAPChunkReceivedTester bobListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer bobEngine = ASAPInternalPeerFS.createASAPPeer( - BOB, BOB_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, bobListener); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare asap immediate bypass // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPAbstractOnlineMessageSender aliceBypass = new ASAPSingleProcessOnlineMessageSender(aliceEngine, aliceStorage); - ASAPAbstractOnlineMessageSender bobBypass = new ASAPSingleProcessOnlineMessageSender(bobEngine, bobStorage); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // setup connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - int portNumber = this.getPortNumber(); - // create connections for both sides - TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b"); - TCPStream bobChannel = new TCPStream(portNumber, false, "b2a"); - - aliceChannel.start(); - bobChannel.start(); - - // wait to connect - aliceChannel.waitForConnection(); - bobChannel.waitForConnection(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // run asap connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // run engine as thread - ASAPPeerHandleConnectionThread aliceEngineThread = new ASAPPeerHandleConnectionThread(aliceEngine, - aliceChannel.getInputStream(), aliceChannel.getOutputStream()); - - aliceEngineThread.start(); - - // and better debugging - no new thread - bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream()); - - // give handleConnection some time. - Thread.sleep(1000); - // create second message after creating a connection - should be bypassed. - //aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2); - - // wait until communication probably ends - System.out.flush(); - System.err.flush(); - Thread.sleep(2000); - System.out.flush(); - System.err.flush(); - - // close connections: note ASAPEngine does NOT close any connection!! - aliceChannel.close(); - bobChannel.close(); - System.out.flush(); - System.err.flush(); - Thread.sleep(1000); - System.out.flush(); - System.err.flush(); - - // check results - - // listener must have been informed about new messages - Assert.assertTrue(bobListener.chunkReceived()); - - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // open incoming storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // get message bob received - ASAPChunkStorage bobIncomingAliceStorage = bobStorage.getReceivedChunksStorage(ALICE); - ASAPInternalChunk bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, aliceInitialEra); - - // #1 - Iterator bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence(); - CharSequence bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE, bobReceivedMessage); - - // #2 - in next era - /* - bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, ASAP.nextEra(aliceInitialEra)); - bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence(); - bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE2, bobReceivedMessage); - - */ - - Thread.sleep(1000); - } - -} diff --git a/src/test/java/net/sharksystem/asap/engine/MultihopTests.java b/src/test/java/net/sharksystem/asap/engine/MultihopTests.java deleted file mode 100644 index 78c8ad3..0000000 --- a/src/test/java/net/sharksystem/asap/engine/MultihopTests.java +++ /dev/null @@ -1,433 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.CountsReceivedMessagesListener; -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import net.sharksystem.asap.ASAPChannel; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.ASAPStorage; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.asap.cmdline.CmdLineUI; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; - -public class MultihopTests { - /** - * Create three storages and engine and let hop one message from a to c - * @throws IOException - * @throws ASAPException - * @throws InterruptedException - */ - //@Test // keep it as an example of batch processor based test case - public void twoHops() throws IOException, ASAPException, InterruptedException { - CmdLineUI ui = new CmdLineUI(System.out); - - ui.doResetASAPStorages(); - - ui.doCreateASAPPeer("Alice"); - ui.doCreateASAPPeer("Bob"); - ui.doCreateASAPPeer("Clara"); - - // create storages - ui.doCreateASAPApp("Alice twoHops"); - ui.doCreateASAPApp("Bob twoHops"); - ui.doCreateASAPApp("Clara twoHops"); - - ui.doSetSendReceivedMessage("Alice:twoHops on"); - ui.doSetSendReceivedMessage("Bob:twoHops on"); - ui.doSetSendReceivedMessage("Clara:twoHops on"); - - // add message to alice storage - String messageAlice2Clara = "HiClara"; - String parameters = "Alice twoHops sn2://abc " + messageAlice2Clara; - ui.doCreateASAPMessage(parameters); - - // remember Alice' era - ASAPInternalStorage aliceStorage = this.getFreshStorageByName(ui, "Alice:twoHops"); - int aliceEraWhenIssuedMessage = aliceStorage.getEra(); - - System.out.println("**************************************************************************"); - System.out.println("** connect Alice with Bob **"); - System.out.println("**************************************************************************"); - // connect alice with bob - ui.doOpen("7070 Alice"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - - ui.doConnect("7070 Bob"); - - // alice should be in era 1 (content has changed before connection) and bob era is 0 - no changes - - // wait a moment - Thread.sleep(1000); - - // kill connections - ui.doKill("all"); - - // alice should stay in era 1 (no content change), bob should be in era 1 received something - - // wait a moment - Thread.sleep(1000); - - System.out.println("**************************************************************************"); - System.out.println("** connect Bob with Clara **"); - System.out.println("**************************************************************************"); - ui.doOpen("8080 Clara"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - ui.doConnect("8080 Bob"); - - // bob should remain in era 1 o changes, clara is era 0 - - // wait a moment - Thread.sleep(1000); - // kill connections - ui.doKill("all"); - // wait a moment - Thread.sleep(1000); - - // get Clara storage - ASAPInternalStorage clara = this.getFreshStorageByName(ui, "Clara:twoHops"); - - /* message was actually from Bob but originated from Alice. It is put - into a incoming folder as it would have been directly received from Alice. - Signatures would allow ensuring if origin was really who mediator claims to be. - */ - ASAPChunkStorage claraAlice = clara.getReceivedChunksStorage("Alice"); - - // clara era was increased after connection terminated - message from bob is in era before current one -// int eraToLook = ASAPEngine.previousEra(clara.getEra()); - ASAPInternalChunk claraABCChat = claraAlice.getChunk("sn2://abc", aliceEraWhenIssuedMessage); - CharSequence message = claraABCChat.getMessagesAsCharSequence().next(); - boolean same = messageAlice2Clara.equalsIgnoreCase(message.toString()); - Assert.assertTrue(same); - } - - @Test - public void connectionWithNoDataExchange() throws IOException, ASAPException, InterruptedException { - CmdLineUI ui = new CmdLineUI(System.out); - - ui.doResetASAPStorages(); - - // create storages - ui.doCreateASAPApp("Alice silent"); - ui.doCreateASAPApp("Bob silent"); - - System.out.println("**************************************************************************"); - System.out.println("** connect Alice with Bob **"); - System.out.println("**************************************************************************"); - // connect alice with bob - ui.doCreateASAPPeer("Alice"); - ui.doOpen("7070 Alice"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - ui.doCreateASAPPeer("Bob"); - - ui.doConnect("7070 Bob"); - - // wait a moment - Thread.sleep(1000); - System.out.println("**************************************************************************"); - System.out.println("** going to kill connection **"); - System.out.println("**************************************************************************"); - - // kill connections - try { ui.doKill("all"); } - catch(Exception e) { - System.out.println("exception - but we called kill(); what would we expect? + " + e.getLocalizedMessage()); - } - } - -// @Test - public void closedChannelTest() throws IOException, ASAPException, InterruptedException { - CmdLineUI ui = new CmdLineUI(System.out); - ui.doResetASAPStorages(); - - ui.doCreateASAPPeer("Alice"); - ui.doCreateASAPPeer("Bob"); - ui.doCreateASAPPeer("Clara"); - ui.doCreateASAPPeer("David"); - - // create app on each peer - ui.doCreateASAPApp("Alice chat"); - ui.doCreateASAPApp("Bob chat"); - ui.doCreateASAPApp("Clara chat"); - ui.doCreateASAPApp("David chat"); - - ui.doSetSendReceivedMessage("Alice:chat on"); - ui.doSetSendReceivedMessage("Bob:chat on"); - ui.doSetSendReceivedMessage("Clara:chat on"); - ui.doSetSendReceivedMessage("David:chat on"); - - // create closed channel with Alice - ui.doCreateASAPChannel(" Alice chat sn2://closedChannel Bob Clara"); - ui.doPrintChannelInformation("Alice chat sn2://closedChannel"); - - // add message - // add message to alice storage - String messageAlice2Clara = "HiClara"; - String parameters = "Alice chat sn2://closedChannel " + messageAlice2Clara; - ui.doCreateASAPMessage(parameters); - - // remember Alice' era - ASAPInternalStorage aliceStorage = this.getFreshStorageByName(ui, "Alice:chat"); - int aliceEraWhenIssuedMessage = aliceStorage.getEra(); - - System.out.println("**************************************************************************"); - System.out.println("** connect Alice with Bob **"); - System.out.println("**************************************************************************"); - // connect alice with bob - ui.doOpen("7070 Alice"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - ui.doConnect("7070 Bob"); - - // alice should be in era 1 (content has changed before connection) and bob era is 0 - no changes - // wait a moment - Thread.sleep(1000); - // kill connections - ui.doKill("all"); - // alice should stay in era 1 (no content change), bob should be in era 1 received something - // wait a moment - Thread.sleep(1000); - // Bob should now have created an closed asap storage with three recipients - ASAPInternalStorage bobStorage = this.getFreshStorageByName(ui, "Bob:chat"); - - ui.doPrintChannelInformation("Bob chat sn2://closedChannel"); - - ASAPChannel bobClosedChannel = bobStorage.getChannel("sn2://closedChannel"); - Set recipientsList = bobClosedChannel.getRecipients(); - boolean aliceFound = false; - boolean bobFound = false; - boolean claraFound = false; - for(CharSequence recipient : recipientsList) { - String recipientString = recipient.toString(); - switch(recipient.toString()) { - case "Alice": aliceFound = true; break; - case "Bob": bobFound = true; break; - case "Clara": claraFound = true; break; - default: Assert.fail("found unexpected recipient: " + recipient); - } - } - - // closed channel created with all recipients and owner? - Assert.assertTrue(aliceFound && bobFound && claraFound); - Assert.assertTrue(bobClosedChannel.getOwner().toString().equalsIgnoreCase("Alice")); - - // message received? - ASAPChunkStorage bobAlice = bobStorage.getReceivedChunksStorage("Alice"); - // clara era was increased after connection terminated - message from bob is in era before current one - ASAPInternalChunk bobABCChat = bobAlice.getChunk("sn2://closedChannel", aliceEraWhenIssuedMessage); - CharSequence message = bobABCChat.getMessagesAsCharSequence().next(); - Assert.assertTrue(messageAlice2Clara.equalsIgnoreCase(message.toString())); - - System.out.println("**************************************************************************"); - System.out.println("** connect Bob with Clara **"); - System.out.println("**************************************************************************"); - // connect alice with bob - ui.doOpen("7071 Bob"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - ui.doConnect("7071 Clara"); - - // alice should be in era 1 (content has changed before connection) and bob era is 0 - no changes - // wait a moment - Thread.sleep(1000); - // kill connections - ui.doKill("all"); - // alice should stay in era 1 (no content change), bob should be in era 1 received something - // wait a moment - Thread.sleep(1000); - // Bob should now have created an closed asap storage with three recipients - ASAPInternalStorage claraStorage = this.getFreshStorageByName(ui, "Clara:chat"); - - ui.doPrintChannelInformation("Clara chat sn2://closedChannel"); - - ASAPChannel claraClosedChannel = bobStorage.getChannel("sn2://closedChannel"); - recipientsList = bobClosedChannel.getRecipients(); - aliceFound = false; - bobFound = false; - claraFound = false; - for(CharSequence recipient : recipientsList) { - String recipientString = recipient.toString(); - switch(recipient.toString()) { - case "Alice": aliceFound = true; break; - case "Bob": bobFound = true; break; - case "Clara": claraFound = true; break; - default: Assert.fail("found unexpected recipient: " + recipient); - } - } - - // closed channel created with all recipients and owner? - Assert.assertTrue(aliceFound && bobFound && claraFound); - Assert.assertTrue(bobClosedChannel.getOwner().toString().equalsIgnoreCase("Alice")); - - // message received? - ASAPChunkStorage claraAlice = claraStorage.getReceivedChunksStorage("Alice"); - // clara era was increased after connection terminated - message from bob is in era before current one - ASAPInternalChunk claraABCChat = claraAlice.getChunk("sn2://closedChannel", aliceEraWhenIssuedMessage); - message = claraABCChat.getMessagesAsCharSequence().next(); - Assert.assertTrue(messageAlice2Clara.equalsIgnoreCase(message.toString())); - - System.out.println("**************************************************************************"); - System.out.println("** connect Clara with David **"); - System.out.println("**************************************************************************"); - // connect alice with bob - ui.doOpen("7072 Clara"); - // wait a moment to give server socket time to be created - Thread.sleep(10); - ui.doConnect("7072 David"); - - // wait a moment - Thread.sleep(1000); - // kill connections - ui.doKill("all"); - // wait a moment - Thread.sleep(1000); - // Bob should now have created an closed asap storage with three recipients - ASAPInternalStorage davidStorage = this.getFreshStorageByName(ui, "David:chat"); - - Assert.assertFalse(davidStorage.channelExists("sn2://closedChannel")); - } - - private ASAPInternalStorage getFreshStorageByName(CmdLineUI ui, String storageName) throws ASAPException, IOException { - String rootFolder = ui.getEngineRootFolderByStorageName(storageName); - return ASAPEngineFS.getExistingASAPEngineFS(rootFolder); - } - - /** - * 1) Alice creates two messages in era 0 - * 2) Alice meets Bob. Alice:0->1, Bob:0. Alice:0 (2) -> Bob (two messages era A:0 received by Bob) - * 3) Bob meets Clara. Bob:0, Clara:0. Alice:0 (2) -> Bob -> Clara (two messages routed to Clara) - * 4) Alice meets Clara. Alice:1, Clara:0. no exchange: Clara is in sync with Alice:0, Clara has no messages at all - * 5) Alice creates another message in A:1 - * 6) Alice meets Clara. Alice:1->2, Clara:0; Alice:1 (2) -> Clara (one message era A:1 received by Clara) - * 7) Bob meets Clara. Bob:0, Clara:0. Alice:1 (1) -> Clara -> Bob (one message routed to Bob) - */ - @Test - public void asapRoutingIsFiniteAndCheckEra() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////// setup test environment - String aliceFolder = TestHelper.getFullRootFolderName(TestConstants.ALICE_ID, MultihopTests.class); - aliceFolder = TestHelper.getFullTempFolderName(aliceFolder, false); - FSUtils.removeFolder(aliceFolder); - - String bobFolder = TestHelper.getFullRootFolderName(TestConstants.BOB_ID, MultihopTests.class); - bobFolder = TestHelper.getFullTempFolderName(bobFolder, false); - FSUtils.removeFolder(bobFolder); - - String claraFolder = TestHelper.getFullRootFolderName(TestConstants.CLARA_ID, MultihopTests.class); - claraFolder = TestHelper.getFullTempFolderName(claraFolder, true); - FSUtils.removeFolder(claraFolder); - - String appName = TestHelper.produceTestAppName(MultihopTests.class); - Collection formats = new ArrayList<>(); - formats.add(appName); - - ////////////////////////////////////// setup test peers - // ALICE - ASAPTestPeerFS alicePeer = new ASAPTestPeerFS(TestConstants.ALICE_ID, aliceFolder, formats); - alicePeer.setASAPRoutingAllowed(appName, true); - CountsReceivedMessagesListener aliceListener = new CountsReceivedMessagesListener(TestConstants.ALICE_ID); - alicePeer.addASAPMessageReceivedListener(appName, aliceListener); - // BOB - ASAPTestPeerFS bobPeer = new ASAPTestPeerFS(TestConstants.BOB_ID, bobFolder, formats); - bobPeer.setASAPRoutingAllowed(appName, true); - CountsReceivedMessagesListener bobListener = new CountsReceivedMessagesListener(TestConstants.BOB_ID); - bobPeer.addASAPMessageReceivedListener(appName, bobListener); - // CLARA - ASAPTestPeerFS claraPeer = new ASAPTestPeerFS(TestConstants.CLARA_ID, claraFolder, formats); - claraPeer.setASAPRoutingAllowed(appName, true); - CountsReceivedMessagesListener claraListener = new CountsReceivedMessagesListener(TestConstants.CLARA_ID); - claraPeer.addASAPMessageReceivedListener(appName, claraListener); - - //////////////////////////////////// Alice creates messages - Thread.sleep(500); // let write logs - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> write two messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - byte[] testMessage1 = TestHelper.produceTestMessage(); - byte[] testMessage2 = TestHelper.produceTestMessage(); - ASAPStorage aliceAppStorage = alicePeer.getASAPStorage(appName); - aliceAppStorage.add(TestConstants.URI, testMessage1); - aliceAppStorage.add(TestConstants.URI, testMessage2); - - //////////////////////////////////// Alice meets Bob - first exchange: Alice:0 (2) -> Bob - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> Alice meets Bob <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - alicePeer.startEncounter(TestHelper.getPortNumber(), bobPeer); - // give your app a moment to process - Thread.sleep(500); - alicePeer.stopEncounter(bobPeer); - Thread.sleep(500); - Assert.assertEquals(1, bobListener.numberOfMessages); - - // check local eras - // one change after connection establishment - Assert.assertEquals(1, alicePeer.getASAPStorage(appName).getEra()); - // no change - receiving message does not change local understanding of an era - Assert.assertEquals(0, bobPeer.getASAPStorage(appName).getEra()); - - //////////////////////////////////// Bob meets Clara - routing Alice:0 (2) -> Bob -> Clara - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bob meets Clara <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - claraPeer.startEncounter(TestHelper.getPortNumber(), bobPeer); - // give your app a moment to process - Thread.sleep(500); - claraPeer.stopEncounter(bobPeer); - Thread.sleep(500); - Assert.assertEquals(1, claraListener.numberOfMessages); - - // no change - receiving message does not change local understanding of an era - Assert.assertEquals(0, bobPeer.getASAPStorage(appName).getEra()); - Assert.assertEquals(0, claraPeer.getASAPStorage(appName).getEra()); - - //////////////////////////////////// Alice meets Clara - nothing: Alice:0 (2) -X Clara already got this - // reset counter on clara side - claraListener.numberOfMessages = 0; - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>> Alice meets Clara <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - alicePeer.startEncounter(TestHelper.getPortNumber(), claraPeer); - // give your app a moment to process - Thread.sleep(500); - alicePeer.stopEncounter(claraPeer); - Thread.sleep(500); - Assert.assertEquals(0, claraListener.numberOfMessages); - - // no change - receiving message does not change local understanding of an era - Assert.assertEquals(1, alicePeer.getASAPStorage(appName).getEra()); - Assert.assertEquals(0, claraPeer.getASAPStorage(appName).getEra()); - - //////////////////////////////////// Alice creates another message - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> Alice writes another messages <<<<<<<<<<<<<<<<<<"); - byte[] testMessage3 = TestHelper.produceTestMessage(); - aliceAppStorage.add(TestConstants.URI, testMessage3); - - - //////////////////////////////////// Alice meets Clara again Alice:1 (1) -> Clara - // reset counter on clara side - claraListener.numberOfMessages = 0; - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>> Alice meets Clara again <<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - alicePeer.startEncounter(TestHelper.getPortNumber(), claraPeer); - // give your app a moment to process - Thread.sleep(500); - alicePeer.stopEncounter(claraPeer); - Thread.sleep(500); - //Thread.sleep(60*1000); - Assert.assertEquals(1, claraListener.numberOfMessages); - - // Alice:1->2 new connection after new data added to channel. - Assert.assertEquals(2, alicePeer.getASAPStorage(appName).getEra()); - // no change - receiving message does not change local understanding of an era - Assert.assertEquals(0, claraPeer.getASAPStorage(appName).getEra()); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/Point2PointTests.java b/src/test/java/net/sharksystem/asap/engine/Point2PointTests.java deleted file mode 100644 index 1ced3e0..0000000 --- a/src/test/java/net/sharksystem/asap/engine/Point2PointTests.java +++ /dev/null @@ -1,406 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.utils.ASAPChunkReceivedTester; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.cmdline.TCPStream; -import org.junit.Test; -import org.junit.Assert; - -import static net.sharksystem.utils.testsupport.TestConstants.*; -import static net.sharksystem.asap.engine.ASAPInternalPeer.DEFAULT_MAX_PROCESSING_TIME; - -/** - * Here are some basic tests and usage examples. - * @author thsc - */ -public class Point2PointTests { - private static final String TEST_CLASS_ROOT_FOLDER = TestConstants.ROOT_DIRECTORY + Point2PointTests.class.getSimpleName() + "/"; - public static final String ALICE_BOB_CHAT_URL = "content://aliceAndBob.talk"; - public static final String CHAT_FORMAT = "application/x-sn2-makan"; - public static final String ALICE_ROOT_FOLDER = TEST_CLASS_ROOT_FOLDER + ALICE_NAME; - public static final String ALICE_APP_FOLDER = ALICE_ROOT_FOLDER + "/appFolder"; - public static final String BOB_ROOT_FOLDER = TEST_CLASS_ROOT_FOLDER + BOB_NAME; - public static final String BOB_APP_FOLDER = BOB_ROOT_FOLDER + "/appFolder"; - public static final String ALICE2BOB_MESSAGE = "Hi Bob"; - // 400 characters - //public static final String ALICE2BOB_MESSAGE2 = "HiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgain"; - public static final String ALICE2BOB_MESSAGE2 = "Hi You Again"; - public static final String BOB2ALICE_MESSAGE = "Hi Alice"; - public static final String BOB2ALICE_MESSAGE2 = "Hi Alice again"; - - private static int portnumber = 7777; - - private int getPortNumber() { - portnumber++; - return portnumber; - } - - @Test - public void notOpenMessageChunkExchange() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - FSUtils.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before - FSUtils.removeFolder(BOB_ROOT_FOLDER); // clean previous version before - - // alice writes a message into chunkStorage - ASAPInternalStorage aliceStorage = - ASAPEngineFS.getASAPStorage(ALICE_NAME, ALICE_APP_FOLDER, CHAT_FORMAT); - - aliceStorage.createChannel(ALICE_BOB_CHAT_URL, BOB_NAME); // Add recipient: make it a non-open channel - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE); - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2); - - // bob does the same - ASAPInternalStorage bobStorage = - ASAPEngineFS.getASAPStorage(BOB_NAME, BOB_APP_FOLDER, CHAT_FORMAT); - - int bobInitialEra = bobStorage.getEra(); - - bobStorage.createChannel(ALICE_BOB_CHAT_URL, ALICE_NAME); // Add recipient: make it a non-open channel - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE); - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE2); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare multi engines // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPChunkReceivedTester aliceListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer aliceEngine = ASAPInternalPeerFS.createASAPPeer( - ALICE_NAME, ALICE_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, aliceListener); - - ASAPChunkReceivedTester bobListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer bobEngine = ASAPInternalPeerFS.createASAPPeer( - BOB_NAME, BOB_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, bobListener); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // setup connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - int portNumber = this.getPortNumber(); - // create connections for both sides - TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b"); - TCPStream bobChannel = new TCPStream(portNumber, false, "b2a"); - - aliceChannel.start(); - bobChannel.start(); - - // wait to connect - aliceChannel.waitForConnection(); - bobChannel.waitForConnection(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // run asap connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // run engine as thread - ASAPPeerHandleConnectionThread aliceEngineThread = new ASAPPeerHandleConnectionThread(aliceEngine, - aliceChannel.getInputStream(), aliceChannel.getOutputStream()); - - aliceEngineThread.start(); - - // and better debugging - no new thread - bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream()); - - // wait until communication probably ends - System.out.flush(); - System.err.flush(); - Thread.sleep(2000); - System.out.flush(); - System.err.flush(); - - // close connections: note ASAPEngine does NOT close any connection!! - aliceChannel.close(); - bobChannel.close(); - System.out.flush(); - System.err.flush(); - Thread.sleep(1000); - System.out.flush(); - System.err.flush(); - - // check results - - // listener must have been informed about new messages - Assert.assertTrue(aliceListener.chunkReceived()); - Assert.assertTrue(bobListener.chunkReceived()); - - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // open incoming storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // get messages alice received - ASAPChunkStorage aliceSenderStored = - aliceStorage.getReceivedChunksStorage(aliceListener.getSenderE2E()); - - ASAPInternalChunk aliceReceivedChunk = - aliceSenderStored.getChunk(aliceListener.getUri(), - aliceListener.getEra()); - - // #1 - Iterator aliceReceivedMessages = aliceReceivedChunk.getMessagesAsCharSequence(); - CharSequence aliceReceivedMessage = aliceReceivedMessages.next(); - Assert.assertEquals(BOB2ALICE_MESSAGE, aliceReceivedMessage); - // #2 - aliceReceivedMessage = aliceReceivedMessages.next(); - Assert.assertEquals(BOB2ALICE_MESSAGE2, aliceReceivedMessage); - - // get message bob received - ASAPChunkStorage bobSenderStored = - bobStorage.getReceivedChunksStorage(bobListener.getSenderE2E()); - - ASAPInternalChunk bobReceivedChunk = - bobSenderStored.getChunk(bobListener.getUri(), - bobListener.getEra()); - - // #1 - Iterator bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence(); - CharSequence bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE, bobReceivedMessage); - // #2 - bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE2, bobReceivedMessage); - - List senderList = aliceStorage.getSender(); - // expect bob - Assert.assertEquals(1, senderList.size()); - Assert.assertTrue(BOB_NAME.equalsIgnoreCase(senderList.get(0).toString())); - - // simulate a sync - bobStorage = ASAPEngineFS.getASAPStorage(BOB_NAME, BOB_APP_FOLDER, CHAT_FORMAT); - Assert.assertEquals(bobInitialEra+2, bobStorage.getEra()); - - Thread.sleep(1000); - } - - @Test - public void usageWithImmediateSync() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - FSUtils.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before - FSUtils.removeFolder(BOB_ROOT_FOLDER); // clean previous version before - - // alice writes a message into chunkStorage - ASAPInternalStorage aliceStorage = ASAPEngineFS.getASAPStorage(ALICE_NAME, ALICE_APP_FOLDER, CHAT_FORMAT); - - int aliceInitialEra = aliceStorage.getEra(); - - aliceStorage.createChannel(ALICE_BOB_CHAT_URL, BOB_NAME); - - // content changed - next change in topology should increase alice era. - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE); - - // bob does the same - ASAPInternalStorage bobStorage = ASAPEngineFS.getASAPStorage(BOB_NAME, BOB_APP_FOLDER, CHAT_FORMAT); - - int bobInitialEra = bobStorage.getEra(); - - bobStorage.createChannel(ALICE_BOB_CHAT_URL, ALICE_NAME); - - // content changed - next change in topology should increase bob era. - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare multi engines // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPChunkReceivedTester aliceListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer aliceEngine = ASAPInternalPeerFS.createASAPPeer( - ALICE_NAME, ALICE_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, aliceListener); - - ASAPChunkReceivedTester bobListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer bobEngine = ASAPInternalPeerFS.createASAPPeer( - BOB_NAME, BOB_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, bobListener); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare asap immediate bypass // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPAbstractOnlineMessageSender aliceBypass = new ASAPSingleProcessOnlineMessageSender(aliceEngine, aliceStorage); - ASAPAbstractOnlineMessageSender bobBypass = new ASAPSingleProcessOnlineMessageSender(bobEngine, bobStorage); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // setup connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - int portNumber = this.getPortNumber(); - // create connections for both sides - TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b"); - TCPStream bobChannel = new TCPStream(portNumber, false, "b2a"); - - aliceChannel.start(); - bobChannel.start(); - - // wait to connect - aliceChannel.waitForConnection(); - bobChannel.waitForConnection(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // run asap connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // run engine as thread - ASAPPeerHandleConnectionThread aliceEngineThread = new ASAPPeerHandleConnectionThread(aliceEngine, - aliceChannel.getInputStream(), aliceChannel.getOutputStream()); - - aliceEngineThread.start(); - - // and better debugging - no new thread - bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream()); - - // give handleConnection some time. - Thread.sleep(1000); - // create second message after creating a connection - should be bypassed. - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2); - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE2); - - // wait until communication probably ends - System.out.flush(); - System.err.flush(); - Thread.sleep(2000); - System.out.flush(); - System.err.flush(); - - // close connections: note ASAPEngine does NOT close any connection!! - aliceChannel.close(); - bobChannel.close(); - System.out.flush(); - System.err.flush(); - Thread.sleep(1000); - System.out.flush(); - System.err.flush(); - - // check results - - // listener must have been informed about new messages - Assert.assertTrue(aliceListener.chunkReceived()); - Assert.assertTrue(bobListener.chunkReceived()); - - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // open incoming storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // get messages alice received - ASAPChunkStorage aliceIncomingBobStorage = aliceStorage.getReceivedChunksStorage(BOB_NAME); - ASAPInternalChunk aliceReceivedChunk = aliceIncomingBobStorage.getChunk(ALICE_BOB_CHAT_URL, bobInitialEra); - - // must be one message - Iterator aliceReceivedMessages = aliceReceivedChunk.getMessagesAsCharSequence(); - CharSequence aliceReceivedMessage = aliceReceivedMessages.next(); - Assert.assertEquals(BOB2ALICE_MESSAGE, aliceReceivedMessage); - - // #2 is in another era - aliceReceivedChunk = aliceIncomingBobStorage.getChunk(ALICE_BOB_CHAT_URL, ASAP.nextEra(bobInitialEra)); - aliceReceivedMessages = aliceReceivedChunk.getMessagesAsCharSequence(); - aliceReceivedMessage = aliceReceivedMessages.next(); - Assert.assertEquals(BOB2ALICE_MESSAGE2, aliceReceivedMessage); - - // get message bob received - ASAPChunkStorage bobIncomingAliceStorage = bobStorage.getReceivedChunksStorage(ALICE_NAME); - ASAPInternalChunk bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, aliceInitialEra); - - // #1 - Iterator bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence(); - CharSequence bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE, bobReceivedMessage); - - // #2 - in next era - bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, ASAP.nextEra(aliceInitialEra)); - bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence(); - bobReceivedMessage = bobReceivedMessages.next(); - Assert.assertEquals(ALICE2BOB_MESSAGE2, bobReceivedMessage); - - Thread.sleep(1000); - } - - @Test - public void killOpenConnection() throws IOException, ASAPException, InterruptedException { - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare storages // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - FSUtils.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before - FSUtils.removeFolder(BOB_ROOT_FOLDER); // clean previous version before - - // alice writes a message into chunkStorage - ASAPInternalStorage aliceStorage = - ASAPEngineFS.getASAPStorage(ALICE_NAME, ALICE_APP_FOLDER, CHAT_FORMAT); - - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE); - aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2); - //aliceStorage.addRecipient(ALICE_BOB_CHAT_URL, BOB); - - // bob does the same - ASAPInternalStorage bobStorage = - ASAPEngineFS.getASAPStorage(BOB_NAME, BOB_APP_FOLDER, CHAT_FORMAT); - - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE); - bobStorage.add(ALICE_BOB_CHAT_URL, BOB2ALICE_MESSAGE2); - //bobStorage.addRecipient(ALICE_BOB_CHAT_URL, ALICE); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // prepare multi engines // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - ASAPChunkReceivedTester aliceListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer aliceEngine = ASAPInternalPeerFS.createASAPPeer(ALICE_ROOT_FOLDER, aliceListener); - - ASAPChunkReceivedTester bobListener = new ASAPChunkReceivedTester(); - ASAPInternalPeer bobEngine = ASAPInternalPeerFS.createASAPPeer(BOB_ROOT_FOLDER, bobListener); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // setup connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - int portNumber = this.getPortNumber(); - // create connections for both sides - TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b"); - TCPStream bobChannel = new TCPStream(portNumber, false, "b2a"); - - aliceChannel.start(); - bobChannel.start(); - - // wait to connect - aliceChannel.waitForConnection(); - bobChannel.waitForConnection(); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // run asap connection // - /////////////////////////////////////////////////////////////////////////////////////////////////// - - // run engine as thread -/* - ASAPEngineThread aliceEngineThread = new ASAPEngineThread(aliceEngine, - aliceChannel.getInputStream(), aliceChannel.getOutputStream()); - - aliceEngineThread.start(); - */ - // and better debugging - no new thread - bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream()); - - // wait until communication probably ends - Thread.sleep(1000); - - // kill connection on bob side - bobChannel.close(); - - Thread.sleep(1000); - System.out.flush(); - System.err.flush(); - - // check results - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/UsageExamples.java b/src/test/java/net/sharksystem/asap/engine/UsageExamples.java deleted file mode 100644 index 18aae46..0000000 --- a/src/test/java/net/sharksystem/asap/engine/UsageExamples.java +++ /dev/null @@ -1,171 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.SharkException; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPChunkStorage; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.utils.ASAPLogHelper; -import net.sharksystem.asap.cmdline.ExampleASAPChunkReceivedListener; -import net.sharksystem.asap.cmdline.TCPStream; -import net.sharksystem.utils.SerializationHelper; -import net.sharksystem.fs.FSUtils; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -public class UsageExamples { - public static final String WORKING_SUB_DIRECTORY = "asapUsageExamples/"; - public static final String ALICE_PEER_NAME = "Alice"; - public static final String BOB_PEER_NAME = "Bob"; - public static final String CHAT_APP = "chat"; - public static final String CHAT_TOPIC = "topicA"; - public static final int EXAMPLE_PORT = 7070; - public static final String EXAMPLE_MESSAGE_STRING = "Hi"; - - @Test - public void basicTwoPartyTest() throws IOException, ASAPException, InterruptedException { - FSUtils.removeFolder(WORKING_SUB_DIRECTORY); // clean previous version before - - ///// Prepare Alice - String aliceFolder = WORKING_SUB_DIRECTORY + ALICE_PEER_NAME; - - // ASAPChunkReceivedListener - an example - ExampleASAPChunkReceivedListener aliceChunkListener = new ExampleASAPChunkReceivedListener(aliceFolder); - - // setup alice peer - ASAPInternalPeer alicePeer = ASAPInternalPeerFS.createASAPPeer(ALICE_PEER_NAME, aliceFolder, aliceChunkListener); - - // setup chat on alice peer - ASAPEngine aliceChatEngine = alicePeer.createEngineByFormat(CHAT_APP); - - // create a message - String messageAlice = EXAMPLE_MESSAGE_STRING; - - // transform to bytes - there are more elaborate ways to produce a byte array of course - byte[] messageBytes = messageAlice.getBytes(); - - // write a message - we are still offline - aliceChatEngine.add(CHAT_TOPIC, messageBytes); - - ///// Prepare Bob - String bobFolder = WORKING_SUB_DIRECTORY + BOB_PEER_NAME; - - // ASAPChunkReceivedListener - an example - ExampleASAPChunkReceivedListener bobChunkListener = new ExampleASAPChunkReceivedListener(bobFolder); - - // setup alice peer - ASAPInternalPeer bobPeer = ASAPInternalPeerFS.createASAPPeer(BOB_PEER_NAME, bobFolder, bobChunkListener); - - // setup chat on alice peer - ASAPEngine bobChatEngine = bobPeer.createEngineByFormat(CHAT_APP); - - /////////////// create a connection - in real apps it is presumably a bluetooth wifi direct etc. connection - // TCPStream is a helper class for connection establishment - TCPStream aliceStream = new TCPStream(EXAMPLE_PORT, true, "alice2bob"); - TCPStream bobStream = new TCPStream(EXAMPLE_PORT, false, "b2a"); - - // start tcp server or client and try to connect - aliceStream.start(); - bobStream.start(); - - // wait until connection is established - aliceStream.waitForConnection(); - bobStream.waitForConnection(); - //////////////// end of connection establishment - a simulation in some way - but real enough. It is real tcp. - - // let both asap peers run an asap session - ASAPPeerHandleConnectionThread aliceThread = new ASAPPeerHandleConnectionThread(alicePeer, - aliceStream.getInputStream(), aliceStream.getOutputStream()); - - // alice is up and running in a thread - aliceThread.start(); - - // run bob in this test thread - bobPeer.handleConnection(bobStream.getInputStream(), bobStream.getOutputStream()); - - // at this point give both asap engines some time to run their asap session - then we check what happened. - Thread.sleep(1000); - - // we assume the asap session was performed - - // bob chunk received listener must have received something - List receivedList = - bobChunkListener.getReceivedList(); - - Assert.assertNotNull(receivedList); - Assert.assertFalse(receivedList.isEmpty()); - - // there must be a single entry - get it - Assert.assertTrue(receivedList.size() == 1); - ExampleASAPChunkReceivedListener.ASAPChunkReceivedParameters parameters = receivedList.get(0); - - // get chunk storage - ASAPChunkStorage receivedChunkStorage = bobChatEngine.getReceivedChunksStorage(parameters.getSender()); - - // get chunk - ASAPInternalChunk chunk = receivedChunkStorage.getChunk(parameters.getUri(), parameters.getEra()); - - Iterator messages = chunk.getMessages(); - - // there must a one and only one - byte[] messageBytesReceived = messages.next(); - - // convert to String - String receivedMessage = new String(messageBytesReceived); - - System.out.println(bobChatEngine.getOwner() + " received a message: " + receivedMessage); - - Assert.assertTrue(receivedMessage.equals(EXAMPLE_MESSAGE_STRING)); - - // make it a bit easier with a helper class - ASAPMessages receivedMessages = - ASAPLogHelper.getMessagesByChunkReceivedInfos(parameters.getFormat(), parameters.getSender(), - parameters.getUri(), - bobFolder, // peers' root directory! - parameters.getEra()); - - Iterator msgInter = receivedMessages.getMessages(); - while(msgInter.hasNext()) { - byte[] msgBytes = msgInter.next(); - String msg = new String(msgBytes); - System.out.println("message received: " + msg); - } - } - - @Test - public void workWithExtraData() throws IOException, SharkException, InterruptedException { - FSUtils.removeFolder(WORKING_SUB_DIRECTORY); // clean previous version before - - ///// Prepare Alice - String aliceFolder = WORKING_SUB_DIRECTORY + ALICE_PEER_NAME; - - // setup alice peer - ASAPInternalPeer alicePeer = ASAPInternalPeerFS.createASAPPeer(ALICE_PEER_NAME, aliceFolder, null); - - String string1 = "TestString"; - String key1 = "testKey"; - byte[] value1 = string1.getBytes(); - - String key2 = "testKey2"; - byte[] value2 = "TestString2".getBytes(); - - alicePeer.putExtra(key1, value1); - alicePeer.putExtra(key2, value2); - - // set up new peer object - ASAPInternalPeer alicePeer2 = ASAPInternalPeerFS.createASAPPeer(ALICE_PEER_NAME, aliceFolder, null); - - byte[] valueR1 = alicePeer2.getExtra(key1); - Assert.assertTrue(SerializationHelper.sameByteArray(value1, valueR1)); - - byte[] valueR2 = alicePeer2.getExtra(key2); - Assert.assertTrue(SerializationHelper.sameByteArray(value2, valueR2)); - - String r1String = new String(valueR1); - Assert.assertTrue(r1String.equals(string1)); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/WhiteBoxTests.java b/src/test/java/net/sharksystem/asap/engine/WhiteBoxTests.java deleted file mode 100644 index cae71b7..0000000 --- a/src/test/java/net/sharksystem/asap/engine/WhiteBoxTests.java +++ /dev/null @@ -1,126 +0,0 @@ -package net.sharksystem.asap.engine; - -import java.io.IOException; -import java.util.Iterator; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.fs.FSUtils; -import org.junit.Assert; -import org.junit.Test; - -/** - * - * @author thsc - */ -public class WhiteBoxTests { - public static final String FORMAT = "format"; - public static final String DUMMY_USER = "dummyUser"; - - public WhiteBoxTests() { - } - - @Test - public void scratch() { - int maxEra = 2^8-1; - int i = 42; - } - - @Test - public void writeReadByteMessages() throws IOException, ASAPException { - String folder = "tests/writeReadByteMessagesTest"; - FSUtils.removeFolder(folder); - - String uri = "test://anURI"; - String firstMessage = "first message"; - String secondMessage = "second message"; - - FSUtils.removeFolder(folder); - ASAPInternalStorage storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - - // convert message into bytes - byte[] messageBytes = firstMessage.getBytes(); - storage.add(uri, messageBytes); - - // convert message into bytes - messageBytes = secondMessage.getBytes(); - storage.add(uri, messageBytes); - - Iterator byteArrayIter = storage.getChunkStorage().getChunk(uri, storage.getEra()).getMessages(); - messageBytes = byteArrayIter.next(); - String message = new String(messageBytes); - Assert.assertTrue(message.equals(firstMessage)); - - messageBytes = byteArrayIter.next(); - message = new String(messageBytes); - Assert.assertTrue(message.equals(secondMessage)); - } - - @Test - public void writeReadStringMessages() throws IOException, ASAPException { - String folder = "tests/writeReadStringMessagesTest"; - FSUtils.removeFolder(folder); - - String uri = "test://anURI"; - String firstMessage = "first message"; - String secondMessage = "second message"; - - ASAPInternalStorage storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - - storage.add(uri, firstMessage); - storage.add(uri, secondMessage); - - Iterator messageIter = storage.getChunkStorage().getChunk(uri, storage.getEra()).getMessagesAsCharSequence(); - String message = messageIter.next().toString(); - Assert.assertTrue(message.equals(firstMessage)); - - message = messageIter.next().toString(); - Assert.assertTrue(message.equals(secondMessage)); - } - - @Test - public void persistentMessage1() throws IOException, ASAPException { - String folder = "tests/persistentMessage1"; - FSUtils.removeFolder(folder); - - String uri = "test://anURI"; - String firstMessage = "first message"; - - ASAPInternalStorage storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - storage.add(uri, firstMessage); - - // re-create storage - storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - - Assert.assertEquals(storage.getChannelURIs().get(0), uri); - - Iterator messageIter = storage.getChunkStorage().getChunk(uri, storage.getEra()).getMessagesAsCharSequence(); - String message = messageIter.next().toString(); - Assert.assertTrue(message.equals(firstMessage)); - } - - @Test - public void testExtraData() throws IOException, ASAPException { - String folder = "tests/testExtraData"; - FSUtils.removeFolder(folder); - - String uri = "test://anURI"; - - FSUtils.removeFolder(folder); - ASAPInternalStorage storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - - String key1 = "key1"; - String value1 = "value1"; - String key2 = "key2"; - String value2 = "value2"; - - storage.putExtra(uri, key1, value1); - storage.putExtra(uri, key2, value2); - - // restore - storage = ASAPEngineFS.getASAPStorage(DUMMY_USER, folder, FORMAT); - Assert.assertEquals(storage.getExtra(uri, key1), value1); - Assert.assertEquals(storage.getExtra(uri, key2), value2); - - Assert.assertEquals(storage.getChannelURIs().get(0), uri); - } -} diff --git a/src/test/java/net/sharksystem/asap/engine/Workbench.java b/src/test/java/net/sharksystem/asap/engine/Workbench.java deleted file mode 100644 index 38b4fa3..0000000 --- a/src/test/java/net/sharksystem/asap/engine/Workbench.java +++ /dev/null @@ -1,167 +0,0 @@ -package net.sharksystem.asap.engine; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPPeerHandleConnectionThread; -import net.sharksystem.asap.cmdline.ExampleASAPChunkReceivedListener; -import net.sharksystem.asap.cmdline.TCPStream; -import net.sharksystem.asap.crypto.InMemoASAPKeyStore; -import net.sharksystem.fs.FSUtils; -import org.junit.Test; - -import java.io.*; -import java.security.KeyPair; - -public class Workbench { - // copy back to UsageExamples - public static final String WORKING_SUB_DIRECTORY = "cryptoTests/"; - public static final String ALICE_PEER_NAME = "Alice"; - public static final String BOB_PEER_NAME = "Bob"; - public static final String CLARA_PEER_NAME = "Clara"; - public static final String APPNAME = "encryptedChat"; - public static final String CHAT_TOPIC = "topicA"; - public static final int EXAMPLE_PORT = 7070; - public static final String EXAMPLE_MESSAGE_STRING = "Hi"; - - @Test - public void scratch() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - - // sender. Ich sende long long, int long und teile das vorher mit - long[] lValues = new long[3]; - int iValue = -1; - lValues[0] = 1; - lValues[1] = 2; - lValues[2] = 3; - - int types = 0; - - // long comes first - types += 0x01; - types = types << 8; - - // another long - types += 0x01; - types = types << 8; - - // an int - types += 0x00; - types = types << 8; - - // another long - types += 0x01; - - // sage was passiert - dos.writeLong(types); - - dos.writeLong(lValues[0]); - dos.writeLong(lValues[1]); - dos.writeInt(iValue); - dos.writeLong(lValues[2]); - System.out.println("l1 == " + lValues[0] + " | l2 == " + lValues[1] + " | i1 == " + iValue + " | l3 == " + lValues[2]); - - // read - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - DataInputStream dis = new DataInputStream(bais); - - // init l index - int lIndex = 0; - - // read Reihenfolge - types = dis.readInt(); - int mask = 0xFF; - mask = mask << 24; - - while (mask > 0) { - if ((types & mask) != 0) { - // long value - lValues[lIndex++] = dis.readLong(); - } else { - // int - iValue = dis.readInt(); - } - mask = mask >> 8; - } - System.out.println("l1 == " + lValues[0] + " | l2 == " + lValues[1] + " | i1 == " + iValue + " | l3 == " + lValues[2]); - } - - @Test - public void routeEncryptedMessage() throws IOException, ASAPException, InterruptedException { - /* - Alice produces an encrypted message with recipient Clara. It is sent to Bob. He cannot encrypt message, - keeps and finally forwards it to Clara. - */ - - // Still something to do. - - // setup keystores - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_PEER_NAME); - - // alice produces a key pair for alice. This would not work in real life - KeyPair keyPairClara = keyStorageAlice.createTestPeer(CLARA_PEER_NAME); - - // there is a keystore but no key excepts Bobs' He cannot verify or encrypt anybody or anything - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_PEER_NAME); - - InMemoASAPKeyStore keyStorageClara = new InMemoASAPKeyStore(CLARA_PEER_NAME, keyPairClara, - System.currentTimeMillis()); - // clara knows Alice as well - keyStorageClara.addKeyPair(ALICE_PEER_NAME, keyStorageAlice.getKeyPair()); - - // clean up ASAP - FSUtils.removeFolder(WORKING_SUB_DIRECTORY); // clean previous version before - - ///// Prepare Alice - String aliceFolder = WORKING_SUB_DIRECTORY + ALICE_PEER_NAME; - ExampleASAPChunkReceivedListener aliceChunkListener = new ExampleASAPChunkReceivedListener(aliceFolder); - ASAPInternalPeer alicePeer = ASAPInternalPeerFS.createASAPPeer(ALICE_PEER_NAME, aliceFolder, aliceChunkListener); - alicePeer.setASAPKeyStore(keyStorageAlice); // set keystore - alicePeer.getASAPCommunicationControl().setSendEncryptedMessages(true); // send encrypted messages - ASAPEngine aliceChatEngine = alicePeer.createEngineByFormat(APPNAME); // create engine - - // create a message - String messageAlice = EXAMPLE_MESSAGE_STRING; - byte[] messageBytes = messageAlice.getBytes(); - aliceChatEngine.add(CHAT_TOPIC, messageBytes); // and write to chat - - ///// Prepare Bob - String bobFolder = WORKING_SUB_DIRECTORY + BOB_PEER_NAME; - ExampleASAPChunkReceivedListener bobChunkListener = new ExampleASAPChunkReceivedListener(bobFolder); - ASAPInternalPeer bobPeer = ASAPInternalPeerFS.createASAPPeer(BOB_PEER_NAME, bobFolder, bobChunkListener); - ASAPEngine bobChatEngine = bobPeer.createEngineByFormat(APPNAME); - - /////////////// create a connection - in real apps it is presumably a bluetooth wifi direct etc. connection - // TCPStream is a helper class for connection establishment - TCPStream aliceStream = new TCPStream(EXAMPLE_PORT, true, "alice2bob"); - TCPStream bobStream = new TCPStream(EXAMPLE_PORT, false, "b2a"); - - // start tcp server or client and try to connect - aliceStream.start(); - bobStream.start(); - - // wait until connection is established - aliceStream.waitForConnection(); - bobStream.waitForConnection(); - //////////////// end of connection establishment - a simulation in some way - but real enough. It is real tcp. - - // let both asap peers run an asap session - ASAPPeerHandleConnectionThread aliceThread = new ASAPPeerHandleConnectionThread(alicePeer, - aliceStream.getInputStream(), aliceStream.getOutputStream()); - aliceThread.start(); - bobPeer.handleConnection(bobStream.getInputStream(), bobStream.getOutputStream()); - Thread.sleep(1000); - - // now Bob should have stored that encrypted message in a special store. - - int i = 42; - - /* - // we assume the asap session was performed - - // bob chunk received listener must have received something - List receivedList = - bobChunkListener.getReceivedList(); - Assert.assertTrue(receivedList.isEmpty()); - */ - } -} diff --git a/src/test/java/net/sharksystem/asap/helper/HelperTester.java b/src/test/java/net/sharksystem/asap/helper/HelperTester.java deleted file mode 100644 index f126e4d..0000000 --- a/src/test/java/net/sharksystem/asap/helper/HelperTester.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.asap.helper; - -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.utils.SerializationHelper; -import org.junit.Test; - -public class HelperTester { - @Test - public void short2bytes() { - long valueL = System.currentTimeMillis(); - - byte[] result = SerializationHelper.long2byteArray(valueL); - - ASAPSerialization.printByteArray(result); - } -} diff --git a/src/test/java/net/sharksystem/asap/mockAndTemplates/ASAPMessageReceivedListenerExample.java b/src/test/java/net/sharksystem/asap/mockAndTemplates/ASAPMessageReceivedListenerExample.java deleted file mode 100644 index d39aedc..0000000 --- a/src/test/java/net/sharksystem/asap/mockAndTemplates/ASAPMessageReceivedListenerExample.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.sharksystem.asap.mockAndTemplates; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessages; -import net.sharksystem.asap.ASAPMessageReceivedListener; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -public class ASAPMessageReceivedListenerExample implements ASAPMessageReceivedListener { - private final String peerName; - - ASAPMessageReceivedListenerExample(String peerName) { - this.peerName = peerName; - } - - public ASAPMessageReceivedListenerExample() { - this(null); - } - - @Override - public void asapMessagesReceived(ASAPMessages messages, - String senderE2E, // E2E part - List asapHop) throws IOException { - - CharSequence format = messages.getFormat(); - CharSequence uri = messages.getURI(); - if (peerName != null) { - System.out.print(peerName); - } - - System.out.println("asap message received (" + format + " | " + uri + "). size == " + messages.size()); - Iterator yourPDUIter = messages.getMessages(); - while (yourPDUIter.hasNext()) { - TestUtils.deserializeExample(yourPDUIter.next()); - } - } -} diff --git a/src/test/java/net/sharksystem/asap/mockAndTemplates/DiscoverPeerAndStartEGChat.java b/src/test/java/net/sharksystem/asap/mockAndTemplates/DiscoverPeerAndStartEGChat.java deleted file mode 100644 index 2fb334d..0000000 --- a/src/test/java/net/sharksystem/asap/mockAndTemplates/DiscoverPeerAndStartEGChat.java +++ /dev/null @@ -1,215 +0,0 @@ -package net.sharksystem.asap.mockAndTemplates; - -import net.sharksystem.asap.*; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import org.junit.Test; - -import java.io.*; -import java.util.*; - -import static net.sharksystem.asap.mockAndTemplates.TestUtils.ALICE; -import static net.sharksystem.asap.mockAndTemplates.TestUtils.BOB; - -/** - * That's an example. It illustrates how an application can detect a new peer in its surrounding by using - * the ASAPEnvironmentChangesListener. It send a message to the newly detected peers. There are two test variants: - * One with the mock, the other with the real asap protocol stack. - * - * Some considerations - * An ASAPEnvironmentChangesListener is called whenever an ASAP peer detects changes in its connections. - * New connection(s) could have been established or connection(s)) are dropped. - * - * For what could such an information be good for? - * We could initiate a game, a chat, ask to come in a get a special discount for our brand new coffee brand - * (location based / point of sales advertisement) etc. pp. - * - * Interesting question: Should we send a message only to this peer with ASAP? - * - * Depends on your apps' security needs. I suggest for most cases: - * Send an asap message to anybody. Use your application data to describe recipient of this message. - * - * Might sound weired at the first glance but consider this: ASAP provides routing in ad-hoc and even scatter nets. - * It only works if any peer is a potential message recipient and for that reason a router, though. - * ASAP peer would route messages from known applications (!) if you set a flag. - * - * Restrictions on ASAP message recipients are restrictions on ASAP routing capabilities. It is if your would - * require a very dedicated IP router to transmit your IP packages in Internet. - * - * Note: Limiting routing peers is a very crucial feature in ASAP. It allows to set up very high secure applications. - * Such applications can define what devices (we talk about hardware) are trustworthy. Other devices would not even - * get notified about any communication. Such applications control their network on a hardware level and not only on - * a logical level. There is hardly a stronger security thinkable. Drawback: such applications must be aware of that - * fact and must maintain their network. - * - * The gossiping nature of ASAP is very welcome in most cases, though. Any peer becomes a potential router. - * Your peer will only route messages from applications you explicitly created in the first place. - * A chat application would not route messages from a chess application if you not explicitly tell otherwise. Moreover: - * - * There is a complete public key infrastructure (PKI) in the ASAP universe. Use it if you want to: - * https://github.com/SharedKnowledge/ASAPCertificateExchange/wiki. - * - * That's the suggested way for most applications: Create an application specific data unit. - * They can also contain the recipient of course. Your messages can be encrypted for the recipient and - * can be signed by sender. - * - * Send those messages to any ASAP peer. ASAP will make the routing and deliver your application messages as soon - * as possible through an ad-hoc (scatter) network. - * - * Following code demonstrates such a first contact behaviour. - * - * @author thsc42 - */ - -public class DiscoverPeerAndStartEGChat { - public static final CharSequence YOUR_APP_NAME = "yourAppName"; - - private class YourApplication implements ASAPEnvironmentChangesListener, ASAPMessageReceivedListener { - private final ASAPPeer simplePeer; - private Set knowPeers = new HashSet<>(); - - public YourApplication(ASAPPeer simplePeer) { - // your application uses asap. - this.simplePeer = simplePeer; - - // listen to changes in the environment - simplePeer.addASAPEnvironmentChangesListener(this); - - // listen to received messages for your application - simplePeer.addASAPMessageReceivedListener(YOUR_APP_NAME, this); - } - - /** - * Called when connection(s) changed - * @param peerList current list of peer we have a connection to - */ - @Override - public void onlinePeersChanged(Set peerList) { - // peer list has changed - maybe there is a new peer around - for(CharSequence maybeNewPeerName : peerList) { - CharSequence newPeerName = maybeNewPeerName; - for (CharSequence peerName : this.knowPeers) { - if(maybeNewPeerName.toString().equalsIgnoreCase(peerName.toString())) { - newPeerName = null; // not new - break; // found in my known peers list, try next in peerList - } - } - if(newPeerName != null) { - // found one - enough for this example - this.doSomethingWith(newPeerName); // example - break; - } - } - } - private void doSomethingWith(CharSequence newPeerName) { - // create a uri - CharSequence uri = "yourApp://" + newPeerName + "_AND_" + this.simplePeer.getPeerID() + "_haveAChat"; - - try { - // create a PDU of your applications - example - byte[] yourMessage = this.serializeYourPDU(newPeerName); - // send a message to any peer - recipient is in your protocol data unit - this.simplePeer.sendASAPMessage(YOUR_APP_NAME, uri, yourMessage); - } catch (ASAPException | IOException e) { - System.out.println("problems: " + e.getLocalizedMessage()); - } - } - - /** - * Called whenever new messaged arrived - * @param messages - * @param asapHop - * @throws IOException - */ - @Override - public void asapMessagesReceived(ASAPMessages messages, - String senderE2E, // E2E part - List asapHop) throws IOException { - Iterator msgIter = messages.getMessages(); - - // you could check uri, e.g. to figure out what chat is addressed, what running game, what POS offering... - CharSequence uri = messages.getURI(); - this.log("got messages ( uri | number ): (" + uri + " | " + messages.size() + ")"); - - // if uri fits - you could do something with the content - your serialized data - while(msgIter.hasNext()) { - byte[] yourAppMessage = msgIter.next(); - this.deserialize(yourAppMessage); - } - } - - private byte[] serializeYourPDU(CharSequence newPeerName) throws IOException { - // just an example - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream daos = new DataOutputStream(baos); - - // write time - daos.writeLong(System.currentTimeMillis()); - // write local name - daos.writeUTF(this.simplePeer.getPeerID().toString()); - // write recipient name - daos.writeUTF(newPeerName.toString()); - daos.writeUTF("Hi there."); - - return baos.toByteArray(); - } - - private void deserialize(byte[] yourAppMessage) throws IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(yourAppMessage); - DataInputStream dis = new DataInputStream(bais); - - // it is an example - StringBuilder sb = new StringBuilder(); - sb.append("received message was created: " + new Date(dis.readLong())); - sb.append("\n"); - - sb.append("sender: " + dis.readUTF()); - sb.append(" | "); - - // you could decide to ignore or handle this message based on recipient - sb.append("recipient: " + dis.readUTF()); - sb.append("\n"); - - sb.append("message: " + dis.readUTF()); - - this.log(sb.toString()); - } - - private void log(String msg) { - StringBuilder sb = new StringBuilder(); - sb.append(">>>>>>>>>>>>>> YOUR APPLICATION | YOUR APPLICATION | YOUR APPLICATION <<<<<<<<<<<<<<<<<<<<<\n"); - sb.append(msg); - sb.append("\n>>>>>>>>>>>>>> YOUR APPLICATION | YOUR APPLICATION | YOUR APPLICATION <<<<<<<<<<<<<<<<<<<<<\n"); - System.out.println(sb.toString()); - } - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// TEST CODE ///////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * This test illustrates how a peer discovery can be used to initiate e.g. a chat a game, a POS business proposition - * or whatever comes to your mind. - */ - public void recognizePeerInNeighbourhood(ASAPPeer alicePeer, ASAPPeer bobPeer) { - // have a look in the constructor or YourApplication - YourApplication aliceInstanceOfYourApplication = new YourApplication(alicePeer); - YourApplication bobInstanceOfYourApplication = new YourApplication(bobPeer); - } - - @Test - public void realASAPVariant() throws IOException, ASAPException, InterruptedException { - // create two peer - here with real ASAP. - Collection formats = new ArrayList<>(); - formats.add(YOUR_APP_NAME); - ASAPTestPeerFS alicePeer = new ASAPTestPeerFS(ALICE, formats); - ASAPTestPeerFS bobPeer = new ASAPTestPeerFS(BOB, formats); - - this.recognizePeerInNeighbourhood(alicePeer, bobPeer); - - // trigger a real asap encounter - that's no mock, it's the real asap engine / protocol stack using TCP/IP. - alicePeer.startEncounter(7777, bobPeer); - - Thread.sleep(1000); - } -} diff --git a/src/test/java/net/sharksystem/asap/mockAndTemplates/TestUtils.java b/src/test/java/net/sharksystem/asap/mockAndTemplates/TestUtils.java deleted file mode 100644 index e6277b3..0000000 --- a/src/test/java/net/sharksystem/asap/mockAndTemplates/TestUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.sharksystem.asap.mockAndTemplates; - -import java.io.*; - -public class TestUtils { - static final CharSequence ALICE = "Alice"; - static final CharSequence BOB = "Bob"; - static final CharSequence YOUR_APP_NAME = "yourAppName"; - static final CharSequence YOUR_URI = "yourSchema://example"; - - /** - * a serialization example - * @param exampleLong - * @param exampleString - * @param exampleBoolean - * @return - */ - public static byte[] serializeExample(long exampleLong, String exampleString, boolean exampleBoolean) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream daos = new DataOutputStream(baos); - - // serialize - daos.writeLong(exampleLong); - daos.writeUTF(exampleString); - daos.writeBoolean(exampleBoolean); - - return baos.toByteArray(); - } - - /** - * a deserialization example - */ - public static void deserializeExample(byte[] serializedData) throws IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(serializedData); - DataInputStream dais = new DataInputStream(bais); - - // deserialize - long exampleLong = dais.readLong(); - String exampleString = dais.readUTF(); - boolean exampleBoolean = dais.readBoolean(); - - // call a methode in your app - - // here: just print - System.out.println("received: " + exampleLong + " | " + exampleString + " | " + exampleBoolean); - } -} diff --git a/src/test/java/net/sharksystem/asap/mockAndTemplates/UseThisAsTemplate4YourAppTests.java b/src/test/java/net/sharksystem/asap/mockAndTemplates/UseThisAsTemplate4YourAppTests.java deleted file mode 100644 index b252834..0000000 --- a/src/test/java/net/sharksystem/asap/mockAndTemplates/UseThisAsTemplate4YourAppTests.java +++ /dev/null @@ -1,123 +0,0 @@ -package net.sharksystem.asap.mockAndTemplates; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPPeer; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import org.junit.Test; - -import java.io.*; -import java.util.ArrayList; -import java.util.Collection; - -import static net.sharksystem.asap.mockAndTemplates.TestUtils.*; - -/** - * An ASAP app communicates by sending messages. First, you must ensure stability in your application. - * Implement methods that serialized and deserialize messages. Implement a listener. Test your app - * by testing scenarios. This class comprises a scenario in two steps. - * - * One tests uses an asap mock. It simulates a message exchange but does not use ASAP at all. - * - * The asapTestExamples is nearly identical with one important difference: The ASAP engines are used. - * - * Note: The test scenarios do not differ at all. Your application and test logic is written once and is tested - * against a mock and later against ASAP. Same interfaces are also available in Android. YOu can spent some - * times by implementing test scenarios. Makes app coding on your target platform much faster. - * - * Test your app first with the mock and afterwards with the ASAP protocol stack. If anything runs smoothly - - * you will have a stable Android or Java app in no time. - */ -public class UseThisAsTemplate4YourAppTests { - private static final int PORT = 7777; - - private static int port = 0; - static int getPortNumber() { - if(UseThisAsTemplate4YourAppTests.port == 0) { - UseThisAsTemplate4YourAppTests.port = PORT; - } else { - UseThisAsTemplate4YourAppTests.port++; - } - - return UseThisAsTemplate4YourAppTests.port; - } - - @Test - public void asapTestExample() throws IOException, ASAPException, InterruptedException { - ///////////////// ALICE ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - Collection formats = new ArrayList<>(); - formats.add(YOUR_APP_NAME); - - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(ALICE, formats); - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(BOB, formats); - - // 1st encounter - this.scenarioPart1(aliceSimplePeer, bobSimplePeer); - - aliceSimplePeer.startEncounter(getPortNumber(), bobSimplePeer); - // give your app a moment to process - Thread.sleep(1000); - // stop encounter - bobSimplePeer.stopEncounter(aliceSimplePeer); - // give your app a moment to process - Thread.sleep(1000); - - // 2nd encounter - this.scenarioPart2(aliceSimplePeer, bobSimplePeer); - - aliceSimplePeer.startEncounter(getPortNumber(), bobSimplePeer); - } - - public void scenarioPart1(ASAPPeer alicePeer, ASAPPeer bobPeer) - throws IOException, ASAPException, InterruptedException { - // simulate ASAP first encounter with full ASAP protocol stack and engines - System.out.println("+++++++++++++++++++ 1st encounter starts soon ++++++++++++++++++++"); - Thread.sleep(50); - - // setup message received listener - this should be replaced with your code - you implement a listener. - ASAPMessageReceivedListenerExample aliceMessageReceivedListenerExample = - new ASAPMessageReceivedListenerExample(); - - alicePeer.addASAPMessageReceivedListener(YOUR_APP_NAME, aliceMessageReceivedListenerExample); - - // example - this should be produced by your application - byte[] serializedData = TestUtils.serializeExample(42, "from alice", true); - - alicePeer.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, serializedData); - - ///////////////// BOB ////////////////////////////////////////////////////////////// - - // this should be replaced with your code - you must implement a listener. - ASAPMessageReceivedListenerExample asapMessageReceivedListenerExample = - new ASAPMessageReceivedListenerExample(); - - // register your listener (or that mock) with asap connection mock - bobPeer.addASAPMessageReceivedListener(YOUR_APP_NAME, asapMessageReceivedListenerExample); - - // bob writes something - bobPeer.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, - TestUtils.serializeExample(43, "from bob", false)); - bobPeer.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, - TestUtils.serializeExample(44, "from bob again", false)); - - - // give your app a moment to process - Thread.sleep(500); - } - - public void scenarioPart2(ASAPPeer alicePeer, ASAPPeer bobPeer) - throws IOException, ASAPException, InterruptedException { - - // bob writes something - bobPeer.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, - TestUtils.serializeExample(43, "third message from bob", false)); - - // simulate second encounter - System.out.println("+++++++++++++++++++ 2nd encounter starts soon ++++++++++++++++++++"); - Thread.sleep(50); - } - - public void testScenarioResults() { - // TODO - } -} diff --git a/src/test/java/net/sharksystem/asap/peer/Point2Point2Test2.java b/src/test/java/net/sharksystem/asap/peer/Point2Point2Test2.java deleted file mode 100644 index 9696f6a..0000000 --- a/src/test/java/net/sharksystem/asap/peer/Point2Point2Test2.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.sharksystem.asap.peer; - -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.testsupport.StoreReceivedMessages; -import net.sharksystem.utils.Utils; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; - -public class Point2Point2Test2 { - public static final String WORKING_SUB_DIRECTORY = TestConstants.ROOT_DIRECTORY + "point2point2/"; - - /** - * An reenactment of a failed Android test - a subdirectory wasn't created or something.. - * @throws IOException - * @throws ASAPException - * @throws InterruptedException - * - */ - @Test - public void point2point1() throws IOException, ASAPException, InterruptedException { - TestHelper.removeFolder(WORKING_SUB_DIRECTORY); - - String appName = "shark/onlineExampleMessages"; - String uri = "asapExample://uriExample"; - byte[] message = "ASAP example message".getBytes(StandardCharsets.UTF_8); - - String aliceID = TestConstants.ALICE_ID; - String bobID = TestConstants.BOB_ID; - String aliceDirectory = WORKING_SUB_DIRECTORY + "/" + aliceID; - String bobDirectory = WORKING_SUB_DIRECTORY + "/" + bobID; - - Collection formats = new ArrayList<>(); - formats.add(appName); - - ///////////////// PEERS ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(aliceID, aliceDirectory, formats); - - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(bobID, bobDirectory, formats); - StoreReceivedMessages bobListener = new StoreReceivedMessages(); - bobSimplePeer.addASAPMessageReceivedListener(appName, bobListener); - - aliceSimplePeer.startEncounter(TestHelper.getPortNumber(), bobSimplePeer); - // give your app a moment to process - Thread.sleep(100); - - // send message - System.out.println("\n>>>>>>>>>>>>>>>>>>> send message #1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - aliceSimplePeer.sendASAPMessage(appName, uri, message); - Thread.sleep(100); - //Thread.sleep(Long.MAX_VALUE); - - Assert.assertEquals(1, bobListener.messageList.size()); - - byte[] messageReceived = bobListener.messageList.get(0).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(messageReceived, message)); - - aliceSimplePeer.stopEncounter(bobSimplePeer); - } -} diff --git a/src/test/java/net/sharksystem/asap/peer/TransientMessages.java b/src/test/java/net/sharksystem/asap/peer/TransientMessages.java deleted file mode 100644 index 79ee725..0000000 --- a/src/test/java/net/sharksystem/asap/peer/TransientMessages.java +++ /dev/null @@ -1,239 +0,0 @@ -package net.sharksystem.asap.peer; - -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.utils.testsupport.TestHelper; -import net.sharksystem.asap.ASAP; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.engine.ASAPInternalChunk; -import net.sharksystem.asap.apps.testsupport.ASAPTestPeerFS; -import net.sharksystem.testsupport.StoreReceivedMessages; -import net.sharksystem.utils.Utils; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - -public class TransientMessages { - public static final String WORKING_SUB_DIRECTORY = TestConstants.ROOT_DIRECTORY + "transientMessages/"; - public static final String ALICE_DIRECTORY = WORKING_SUB_DIRECTORY + "/" + TestConstants.ALICE_NAME; - public static final String BOB_DIRECTORY = WORKING_SUB_DIRECTORY + "/" + TestConstants.BOB_NAME; - - public static final String APPNAME = "asap/transient"; - - @Test - public void slowlyTransientMessagesExchangeAlice2Bob() throws IOException, ASAPException, InterruptedException { - int numberOfMessages = 3; - int waitBeforeMessagesInMillis = 500; - String messageBody = "SlowlyTestMessage"; - TestHelper.removeFolder(WORKING_SUB_DIRECTORY); - Collection formats = new ArrayList<>(); - formats.add(APPNAME); - - ///////////////// ALICE ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(TestConstants.ALICE_ID, ALICE_DIRECTORY, formats); - StoreReceivedMessages aliceListener = new StoreReceivedMessages(); - aliceSimplePeer.addASAPMessageReceivedListener(APPNAME, aliceListener); - - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(TestConstants.BOB_ID, BOB_DIRECTORY, formats); - StoreReceivedMessages bobListener = new StoreReceivedMessages(); - bobSimplePeer.addASAPMessageReceivedListener(APPNAME, bobListener); - - aliceSimplePeer.startEncounter(TestHelper.getPortNumber(), bobSimplePeer); - // give your app a moment to process - Thread.sleep(100); - - for (int i = 0; i < numberOfMessages; i++) { - // exchange transient messages - System.out.println("\n>>>>>>>>>>>>>>>>>>> send transient message #" + - i + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - - aliceSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, new byte[]{(byte) i}); - Thread.sleep(waitBeforeMessagesInMillis); - } - - // stop encounter - Thread.sleep(1000); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>> Stop Encounter"); - bobSimplePeer.stopEncounter(aliceSimplePeer); - // give your app a moment to process - Thread.sleep(100); - - Assert.assertEquals(numberOfMessages, bobListener.messageList.size()); - - for (int i = 0; i < numberOfMessages; i++) { - byte[] message = bobListener.messageList.get(i).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, new byte[]{(byte) i})); - } - } - - @Test - public void exchangeTransientMessagesAlice2Bob() throws IOException, ASAPException, InterruptedException { - TestHelper.removeFolder(WORKING_SUB_DIRECTORY); - Collection formats = new ArrayList<>(); - formats.add(APPNAME); - - ///////////////// ALICE ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(TestConstants.ALICE_ID, ALICE_DIRECTORY, formats); - StoreReceivedMessages aliceListener = new StoreReceivedMessages(); - aliceSimplePeer.addASAPMessageReceivedListener(APPNAME, aliceListener); - - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(TestConstants.BOB_ID, BOB_DIRECTORY, formats); - StoreReceivedMessages bobListener = new StoreReceivedMessages(); - bobSimplePeer.addASAPMessageReceivedListener(APPNAME, bobListener); - - aliceSimplePeer.startEncounter(TestHelper.getPortNumber(), bobSimplePeer); - // give your app a moment to process - Thread.sleep(100); - - // exchange transient messages - System.out.println("\n>>>>>>>>>>>>>>>>>>> send transient message #1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - aliceSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_ALICE_TO_BOB_1); - Thread.sleep(500); - - // and another set - System.out.println("\n>>>>>>>>>>>>>>>>>>> send transient message #2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - aliceSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_ALICE_TO_BOB_2); - - // stop encounter - Thread.sleep(500); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>> Stop Encounter"); - bobSimplePeer.stopEncounter(aliceSimplePeer); - // give your app a moment to process - Thread.sleep(500); - - Assert.assertEquals(2, bobListener.messageList.size()); - - byte[] message = bobListener.messageList.get(0).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_ALICE_TO_BOB_1)); - message = bobListener.messageList.get(1).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_ALICE_TO_BOB_2)); - - // transient!! there must be no record - try { - Assert.assertEquals(0, - aliceSimplePeer.getASAPStorage(APPNAME).getChannel(TestConstants.URI).getMessages().size()); - } - catch(ASAPException e) { - // ok - no trace - } - try { - Assert.assertEquals(0, - bobSimplePeer.getASAPStorage(APPNAME).getChannel(TestConstants.URI).getMessages().size()); - } - catch(ASAPException e) { - // ok - no trace - } - - try { - ASAPInternalChunk chunk = aliceSimplePeer.getASAPStorage(APPNAME).getIncomingStorage(TestConstants.BOB_ID) - .getChunkStorage().getChunk(TestConstants.URI, ASAP.TRANSIENT_ERA); - - Assert.assertFalse(chunk.getMessages().hasNext()); - } - catch(ASAPException e) { - // ok there must be no trace - } - - try { - ASAPInternalChunk chunk = bobSimplePeer.getASAPStorage(APPNAME).getIncomingStorage(TestConstants.BOB_ID) - .getChunkStorage().getChunk(TestConstants.URI, ASAP.TRANSIENT_ERA); - - Assert.assertFalse(chunk.getMessages().hasNext()); - } - catch(ASAPException e) { - // ok there must be no trace - } - } - - @Test - public void exchangeTransientMessagesBackAndForth() throws IOException, ASAPException, InterruptedException { - TestHelper.removeFolder(WORKING_SUB_DIRECTORY); - Collection formats = new ArrayList<>(); - formats.add(APPNAME); - - ///////////////// ALICE ////////////////////////////////////////////////////////////// - // setup mocked peer / asap application and activity in android - ASAPTestPeerFS aliceSimplePeer = new ASAPTestPeerFS(TestConstants.ALICE_ID, ALICE_DIRECTORY, formats); - StoreReceivedMessages aliceListener = new StoreReceivedMessages(); - aliceSimplePeer.addASAPMessageReceivedListener(APPNAME, aliceListener); - - ASAPTestPeerFS bobSimplePeer = new ASAPTestPeerFS(TestConstants.BOB_ID, BOB_DIRECTORY, formats); - StoreReceivedMessages bobListener = new StoreReceivedMessages(); - bobSimplePeer.addASAPMessageReceivedListener(APPNAME, bobListener); - - aliceSimplePeer.startEncounter(TestHelper.getPortNumber(), bobSimplePeer); - // give your app a moment to process - Thread.sleep(100); - - // exchange transient messages - System.out.println("\n>>>>>>>>>>>>>>>>>>> send transient messages #1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - aliceSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_ALICE_TO_BOB_1); - bobSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_BOB_TO_ALICE_1); - Thread.sleep(500); - - // and another set - System.out.println("\n>>>>>>>>>>>>>>>>>>> send transient messages #2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - aliceSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_ALICE_TO_BOB_2); - bobSimplePeer.sendTransientASAPMessage(APPNAME, TestConstants.URI, TestConstants.MESSAGE_BOB_TO_ALICE_2); - - // give your app a moment to process - Thread.sleep(100); - // stop encounter - System.out.println(">>>>>>>>>>>>>>>>>>>>>>> Stop Encounter"); - bobSimplePeer.stopEncounter(aliceSimplePeer); - Thread.sleep(100); - - Assert.assertEquals(2, aliceListener.messageList.size()); - Assert.assertEquals(2, bobListener.messageList.size()); - - byte[] message = aliceListener.messageList.get(0).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_BOB_TO_ALICE_1)); - message = aliceListener.messageList.get(1).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_BOB_TO_ALICE_2)); - - message = bobListener.messageList.get(0).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_ALICE_TO_BOB_1)); - message = bobListener.messageList.get(1).getMessages().next(); - Assert.assertTrue(Utils.compareArrays(message, TestConstants.MESSAGE_ALICE_TO_BOB_2)); - - // transient!! there must be no record - try { - Assert.assertEquals(0, - aliceSimplePeer.getASAPStorage(APPNAME).getChannel(TestConstants.URI).getMessages().size()); - } - catch(ASAPException e) { - // ok - no trace - } - try { - Assert.assertEquals(0, - bobSimplePeer.getASAPStorage(APPNAME).getChannel(TestConstants.URI).getMessages().size()); - } - catch(ASAPException e) { - // ok - no trace - } - - try { - ASAPInternalChunk chunk = aliceSimplePeer.getASAPStorage(APPNAME).getIncomingStorage(TestConstants.BOB_ID) - .getChunkStorage().getChunk(TestConstants.URI, ASAP.TRANSIENT_ERA); - - Assert.assertFalse(chunk.getMessages().hasNext()); - } - catch(ASAPException e) { - // ok there must be no trace - } - - try { - ASAPInternalChunk chunk = bobSimplePeer.getASAPStorage(APPNAME).getIncomingStorage(TestConstants.BOB_ID) - .getChunkStorage().getChunk(TestConstants.URI, ASAP.TRANSIENT_ERA); - - Assert.assertFalse(chunk.getMessages().hasNext()); - } - catch(ASAPException e) { - // ok there must be no trace - } - } -} diff --git a/src/test/java/net/sharksystem/asap/protocol/PDUTests.java b/src/test/java/net/sharksystem/asap/protocol/PDUTests.java deleted file mode 100644 index 0645765..0000000 --- a/src/test/java/net/sharksystem/asap/protocol/PDUTests.java +++ /dev/null @@ -1,575 +0,0 @@ -package net.sharksystem.asap.protocol; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPSecurityException; -import net.sharksystem.asap.crypto.InMemoASAPKeyStore; -import net.sharksystem.asap.protocol.*; -import org.junit.Assert; -import org.junit.Test; - -import java.io.*; -import java.security.KeyPair; -import java.util.ArrayList; -import java.util.List; - -public class PDUTests { - public static final String ALICE_ID = "Alice"; - public static final String BOB_ID = "Bob"; - public static final String CLARA_ID = "Clara"; -/* - @Test - public void sendAndReceiveOffer() throws IOException, ASAPException { - - ASAP_1_0 protocolEngine = new ASAP_Modem_Impl(); - - String peer = "Alice"; - String channel = "AliceURI"; - String format = "format"; - int era = 1; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); -*/ - - - /* - void offer(CharSequence peer, CharSequence format, CharSequence channel, int era, OutputStream os, boolean signed) - throws IOException, ASAPException; - */ -/* - protocolEngine.offer(peer, format, channel, era, os, false); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = protocolEngine.readPDU(is); - - ASAP_OfferPDU_1_0 offerPDU = (ASAP_OfferPDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(offerPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(offerPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(offerPDU.getSender().equalsIgnoreCase(peer)); - Assert.assertEquals(offerPDU.getEra(), era); - } -*/ - - //////////////////// interest ///////////////////////////////////////// - @Test - public void sendAndReceiveInterest() throws IOException, ASAPException { - ASAP_1_0 protocolEngine = new ASAP_Modem_Impl(); - - String sender = "Alice"; - String recipient = "Bob"; - String channel = "AliceURI"; - String format = "format"; - int eraFrom = 1; - int eraTo = 2; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - protocolEngine.interest(sender, recipient, format, channel, eraFrom, eraTo, os, false); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = protocolEngine.readPDU(is); - - ASAP_Interest_PDU_1_0 interestPDU = (ASAP_Interest_PDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(interestPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(interestPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(interestPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(interestPDU.getRecipient().equalsIgnoreCase(recipient)); - Assert.assertEquals(interestPDU.getEraFrom(), eraFrom); - Assert.assertEquals(interestPDU.getEraTo(), eraTo); - } - - // protocol.interest(this.owner, null, null, null, -1, -1, os, false); - @Test - public void sendAndReceiveInterest2() throws IOException, ASAPException { - ASAP_1_0 protocolEngine = new ASAP_Modem_Impl(); - - String sender = "Alice"; - String recipient = null; - String channel = null; - String format = null; // will be corrected - /* - int eraFrom = ERA_NOT_DEFINED; - int eraTo = ERA_NOT_DEFINED; - */ - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - protocolEngine.interest(sender, recipient, format, channel, os); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = protocolEngine.readPDU(is); - - ASAP_Interest_PDU_1_0 interestPDU = (ASAP_Interest_PDU_1_0) asap_pdu_1_0; - - Assert.assertFalse(interestPDU.channelSet()); - Assert.assertTrue(interestPDU.getFormat().equalsIgnoreCase(ASAP_1_0.ANY_FORMAT.toString())); - Assert.assertTrue(interestPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(interestPDU.senderSet()); - Assert.assertFalse(interestPDU.recipientSet()); - Assert.assertFalse(interestPDU.eraFromSet()); - Assert.assertFalse(interestPDU.eraToSet()); - } - - @Test - public void sendAndReceiveInterestEncrypted() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID, bobKeyPair, - System.currentTimeMillis()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - /////////////////////// encrypted - asapModemAlice.interest(sender, recipient, format, channel, os,false, true); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_Interest_PDU_1_0 interestPDU = (ASAP_Interest_PDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(interestPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(interestPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(interestPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(interestPDU.getRecipient().equalsIgnoreCase(recipient)); - } - - @Test - public void sendAndReceiveInterestSignedNotEncrypted() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID, bobKeyPair, - System.currentTimeMillis()); - keyStorageBob.addKeyPair(ALICE_ID, keyStorageAlice.getKeyPair()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - /////////////////////// encrypted - asapModemAlice.interest(sender, recipient, format, channel, os,true, false); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_Interest_PDU_1_0 interestPDU = (ASAP_Interest_PDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(interestPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(interestPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(interestPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(interestPDU.getRecipient().equalsIgnoreCase(recipient)); - Assert.assertTrue(interestPDU.verified()); - } - - @Test - public void sendAndReceiveInterestSignedAndEncrypted() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID,bobKeyPair,System.currentTimeMillis()); - keyStorageBob.addKeyPair(ALICE_ID, keyStorageAlice.getKeyPair()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - /////////////////////// encrypted - asapModemAlice.interest(sender, recipient, format, channel, os,true, true); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_Interest_PDU_1_0 interestPDU = (ASAP_Interest_PDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(interestPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(interestPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(interestPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(interestPDU.getRecipient().equalsIgnoreCase(recipient)); - Assert.assertTrue(interestPDU.encrypted()); - Assert.assertTrue(interestPDU.verified()); - } - - @Test(expected = ASAPSecurityException.class) - public void sendEncryptedMessageNotToRecipient() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID, bobKeyPair,System.currentTimeMillis()); - - // add Clara - InMemoASAPKeyStore keyStorageClara = new InMemoASAPKeyStore(CLARA_ID); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - //ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - ASAP_1_0 asapModemClara = new ASAP_Modem_Impl(keyStorageClara); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - /////////////////////// create encrypted message for bob - asapModemAlice.interest(sender, recipient, format, channel, os,false, true); - - // try to read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - // and send to clara. It should fail, but: - System.out.println("We need a feature that handles / redistributes unencryptable messages"); - asapModemClara.readPDU(is); -// ASAP_PDU_1_0 asap_pdu_1_0 = asapModemClara.readPDU(is); - } - - //////////////////// assimilate ///////////////////////////////////////// - @Test - public void sendAndReceiveAssimilate() throws IOException, ASAPException { - ASAP_1_0 protocolEngine = new ASAP_Modem_Impl(); - - String sender = "Alice"; - String recipient = "Bob"; - String channel = "AliceURI"; - String format = "format"; - int era = 1; - - String testString1 = "data1"; - String testString2 = "data2 longer"; - List offsetsList = new ArrayList(); - - byte[] testData1 = testString1.getBytes(); - byte[] testData2 = testString2.getBytes(); - long len = testData1.length; - offsetsList.add(len); - - ByteArrayOutputStream testDataOutputStream = new ByteArrayOutputStream(); - - testDataOutputStream.write(testData1); - testDataOutputStream.write(testData2); - - byte[] data = testDataOutputStream.toByteArray(); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - protocolEngine.assimilate(sender, recipient, format, channel, era, offsetsList, null, data, os,false); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = protocolEngine.readPDU(is); - - ASAP_AssimilationPDU_1_0 assimilationPDU = (ASAP_AssimilationPDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(assimilationPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(assimilationPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(assimilationPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(assimilationPDU.getRecipientPeer().equalsIgnoreCase(recipient)); - Assert.assertEquals(assimilationPDU.getEra(), era); - - byte[] data_received = assimilationPDU.getData(); - List offsets_received = assimilationPDU.getMessageOffsets(); - // one entry assumed - int offset = offsets_received.get(0); - - byte[] data_r1 = new byte[offset]; - for(int i = 0; i < offset; i++) { - data_r1[i] = data_received[i]; - } - - int remainingByteNumber = data_received.length-offset; - byte[] data_r2 = new byte[remainingByteNumber]; - for(int i = 0; i < remainingByteNumber; i++) { - data_r2[i] = data_received[i+offset]; - } - - Assert.assertTrue(new String(data_r1).equalsIgnoreCase(testString1)); - Assert.assertTrue(new String(data_r2).equalsIgnoreCase(testString2)); - } - - @Test - public void sendAndReceiveAssimilateSignedAndEncrypted() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID,bobKeyPair,System.currentTimeMillis()); - keyStorageBob.addKeyPair(ALICE_ID, keyStorageAlice.getKeyPair()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - int era = 1; - - String testString1 = "data1"; - String testString2 = "data2 longer"; - List offsetsList = new ArrayList(); - - byte[] testData1 = testString1.getBytes(); - byte[] testData2 = testString2.getBytes(); - long len = testData1.length; - offsetsList.add(len); - - ByteArrayOutputStream testDataOutputStream = new ByteArrayOutputStream(); - - testDataOutputStream.write(testData1); - testDataOutputStream.write(testData2); - - byte[] data = testDataOutputStream.toByteArray(); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - - asapModemAlice.assimilate(sender, recipient, format, channel, era, offsetsList, null, data, os, - true, true); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_AssimilationPDU_1_0 assimilationPDU = (ASAP_AssimilationPDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(assimilationPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(assimilationPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(assimilationPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(assimilationPDU.getRecipientPeer().equalsIgnoreCase(recipient)); - Assert.assertEquals(assimilationPDU.getEra(), era); - - byte[] data_received = assimilationPDU.getData(); - List offsets_received = assimilationPDU.getMessageOffsets(); - // one entry assumed - int offset = offsets_received.get(0); - - byte[] data_r1 = new byte[offset]; - for(int i = 0; i < offset; i++) { - data_r1[i] = data_received[i]; - } - - int remainingByteNumber = data_received.length-offset; - byte[] data_r2 = new byte[remainingByteNumber]; - for(int i = 0; i < remainingByteNumber; i++) { - data_r2[i] = data_received[i+offset]; - } - - Assert.assertTrue(new String(data_r1).equalsIgnoreCase(testString1)); - Assert.assertTrue(new String(data_r2).equalsIgnoreCase(testString2)); - } - - @Test - public void sendAndReceiveAssimilateSigned() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID,bobKeyPair,System.currentTimeMillis()); - keyStorageBob.addKeyPair(ALICE_ID, keyStorageAlice.getKeyPair()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - int era = 1; - - String testString1 = "data1"; - String testString2 = "data2 longer"; - List offsetsList = new ArrayList(); - - byte[] testData1 = testString1.getBytes(); - byte[] testData2 = testString2.getBytes(); - long len = testData1.length; - offsetsList.add(len); - - ByteArrayOutputStream testDataOutputStream = new ByteArrayOutputStream(); - - testDataOutputStream.write(testData1); - testDataOutputStream.write(testData2); - - byte[] data = testDataOutputStream.toByteArray(); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - - asapModemAlice.assimilate(sender, recipient, format, channel, era, offsetsList, null, data, os, - true, false); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_AssimilationPDU_1_0 assimilationPDU = (ASAP_AssimilationPDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(assimilationPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(assimilationPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(assimilationPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(assimilationPDU.getRecipientPeer().equalsIgnoreCase(recipient)); - Assert.assertEquals(assimilationPDU.getEra(), era); - - byte[] data_received = assimilationPDU.getData(); - List offsets_received = assimilationPDU.getMessageOffsets(); - // one entry assumed - int offsetInt = offsets_received.get(0); - - byte[] data_r1 = new byte[offsetInt]; - for(int i = 0; i < offsetInt; i++) { - data_r1[i] = data_received[i]; - } - - int remainingByteNumber = data_received.length-offsetInt; - byte[] data_r2 = new byte[remainingByteNumber]; - for(int i = 0; i < remainingByteNumber; i++) { - data_r2[i] = data_received[i+offsetInt]; - } - - Assert.assertTrue(new String(data_r1).equalsIgnoreCase(testString1)); - Assert.assertTrue(new String(data_r2).equalsIgnoreCase(testString2)); - - //// taken from ASAPEngine.handleAssimilate - List messageOffsets = assimilationPDU.getMessageOffsets(); - - // iterate messages and stream into chunk - InputStream protocolInputStream = assimilationPDU.getInputStream(); - long offset = 0; - for(long nextOffset : messageOffsets) { - //<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>debug - // simulate read - long length = nextOffset - offsetInt; - while(length-- > 0) { - protocolInputStream.read(); - } - offset = nextOffset; - } - StringBuilder b = new StringBuilder(); - b.append("going to read last message: from offset "); - b.append(offset); - b.append(" to end of file - total length: "); - b.append(assimilationPDU.getLength()); - System.out.println(b.toString()); - } - - @Test - public void sendAndReceiveAssimilateEncrypted() throws IOException, ASAPException { - InMemoASAPKeyStore keyStorageAlice = new InMemoASAPKeyStore(ALICE_ID); - - // add Bob - KeyPair bobKeyPair = keyStorageAlice.createTestPeer(BOB_ID); - InMemoASAPKeyStore keyStorageBob = new InMemoASAPKeyStore(BOB_ID,bobKeyPair,System.currentTimeMillis()); - keyStorageBob.addKeyPair(ALICE_ID, keyStorageAlice.getKeyPair()); - - ASAP_1_0 asapModemAlice = new ASAP_Modem_Impl(keyStorageAlice); - ASAP_1_0 asapModemBob = new ASAP_Modem_Impl(keyStorageBob); - - String sender = ALICE_ID; - String recipient = BOB_ID; - String channel = "AliceURI"; - String format = "format"; - int era = 1; - - String testString1 = "data1"; - String testString2 = "data2 longer"; - List offsetsList = new ArrayList(); - - byte[] testData1 = testString1.getBytes(); - byte[] testData2 = testString2.getBytes(); - long len = testData1.length; - offsetsList.add(len); - - ByteArrayOutputStream testDataOutputStream = new ByteArrayOutputStream(); - - testDataOutputStream.write(testData1); - testDataOutputStream.write(testData2); - - byte[] data = testDataOutputStream.toByteArray(); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - - asapModemAlice.assimilate(sender, recipient, format, channel, era, offsetsList, null, data, os, - false, true); - - // try t read output - InputStream is = new ByteArrayInputStream(os.toByteArray()); - - ASAP_PDU_1_0 asap_pdu_1_0 = asapModemBob.readPDU(is); - - ASAP_AssimilationPDU_1_0 assimilationPDU = (ASAP_AssimilationPDU_1_0) asap_pdu_1_0; - - Assert.assertTrue(assimilationPDU.getChannelUri().equalsIgnoreCase(channel)); - Assert.assertTrue(assimilationPDU.getFormat().equalsIgnoreCase(format)); - Assert.assertTrue(assimilationPDU.getSender().equalsIgnoreCase(sender)); - Assert.assertTrue(assimilationPDU.getRecipientPeer().equalsIgnoreCase(recipient)); - Assert.assertEquals(assimilationPDU.getEra(), era); - - byte[] data_received = assimilationPDU.getData(); - List offsets_received = assimilationPDU.getMessageOffsets(); - // one entry assumed - int offset = offsets_received.get(0); - - byte[] data_r1 = new byte[offset]; - for(int i = 0; i < offset; i++) { - data_r1[i] = data_received[i]; - } - - int remainingByteNumber = data_received.length-offset; - byte[] data_r2 = new byte[remainingByteNumber]; - for(int i = 0; i < remainingByteNumber; i++) { - data_r2[i] = data_received[i+offset]; - } - - Assert.assertTrue(new String(data_r1).equalsIgnoreCase(testString1)); - Assert.assertTrue(new String(data_r2).equalsIgnoreCase(testString2)); - } -} diff --git a/src/test/java/net/sharksystem/asap/serialization/SerializationTests.java b/src/test/java/net/sharksystem/asap/serialization/SerializationTests.java deleted file mode 100644 index 59d28f2..0000000 --- a/src/test/java/net/sharksystem/asap/serialization/SerializationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.sharksystem.asap.serialization; - -import net.sharksystem.asap.ASAPHopImpl; -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPEncounterConnectionType; -import net.sharksystem.asap.utils.ASAPSerialization; -import net.sharksystem.asap.utils.PeerIDHelper; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -public class SerializationTests { - @Test - public void test1() throws IOException, ASAPException { - String messageIn = "I am Alice"; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeCharSequenceParameter(messageIn, baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - String messageOut = ASAPSerialization.readCharSequenceParameter(bais); - - Assert.assertTrue(messageOut.equals(messageIn)); - } - - @Test - public void serializeASAPHopListLen1() throws IOException, ASAPException { - List exampleList = new ArrayList<>(); - - exampleList.add(new ASAPHopImpl("Alice", true, true, ASAPEncounterConnectionType.ASAP_HUB)); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeASAPHopList(exampleList, baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - List receivedList = ASAPSerialization.readASAPHopList(bais); - - Assert.assertEquals(exampleList.size(), receivedList.size()); - for(int i = 0; i < exampleList.size(); i++) { - ASAPHop origHop = exampleList.get(i); - ASAPHop receivedHop = receivedList.get(i); - - Assert.assertTrue(PeerIDHelper.sameID(origHop.sender(), receivedHop.sender())); - Assert.assertTrue(origHop.verified() == receivedHop.verified()); - Assert.assertTrue(origHop.encrypted() == receivedHop.encrypted()); - Assert.assertTrue(origHop.getConnectionType() == receivedHop.getConnectionType()); - } - } - - @Test - public void serializeASAPHopListLen5() throws IOException, ASAPException { - List exampleList = new ArrayList<>(); - - exampleList.add(new ASAPHopImpl("Alice", true, true, ASAPEncounterConnectionType.ASAP_HUB)); - exampleList.add(new ASAPHopImpl("Bob", false, true, ASAPEncounterConnectionType.INTERNET)); - exampleList.add(new ASAPHopImpl("Clara", false, false, ASAPEncounterConnectionType.AD_HOC_LAYER_2_NETWORK)); - exampleList.add(new ASAPHopImpl("David", true, false, ASAPEncounterConnectionType.ONION_NETWORK)); - exampleList.add(new ASAPHopImpl("Eveline", true, false, ASAPEncounterConnectionType.UNKNOWN)); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ASAPSerialization.writeASAPHopList(exampleList, baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - List receivedList = ASAPSerialization.readASAPHopList(bais); - - Assert.assertEquals(exampleList.size(), receivedList.size()); - for(int i = 0; i < exampleList.size(); i++) { - ASAPHop origHop = exampleList.get(i); - ASAPHop receivedHop = receivedList.get(i); - - Assert.assertTrue(PeerIDHelper.sameID(origHop.sender(), receivedHop.sender())); - Assert.assertTrue(origHop.verified() == receivedHop.verified()); - Assert.assertTrue(origHop.encrypted() == receivedHop.encrypted()); - Assert.assertTrue(origHop.getConnectionType() == receivedHop.getConnectionType()); - } - } -} diff --git a/src/test/java/net/sharksystem/asap/storage/StorageTests.java b/src/test/java/net/sharksystem/asap/storage/StorageTests.java deleted file mode 100644 index cdb5ffc..0000000 --- a/src/test/java/net/sharksystem/asap/storage/StorageTests.java +++ /dev/null @@ -1,209 +0,0 @@ -package net.sharksystem.asap.storage; - -import net.sharksystem.fs.FSUtils; -import net.sharksystem.utils.testsupport.TestConstants; -import net.sharksystem.asap.*; -import net.sharksystem.asap.engine.ASAPEngine; -import net.sharksystem.asap.engine.ASAPEngineFS; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.Iterator; - -public class StorageTests { - static final String ROOTFOLDER = TestConstants.ROOT_DIRECTORY + StorageTests.class.getSimpleName() + "/"; - static final String ALICEFOLDER = ROOTFOLDER + TestConstants.ALICE_NAME; - static final String ALICEFOLDER_0 = ALICEFOLDER + "_Test_0"; - static final String ALICEFOLDER_1 = ALICEFOLDER + "_Test_1"; - static final String ALICEFOLDER_2 = ALICEFOLDER + "_Test_2"; - static final String ALICEFOLDER_3 = ALICEFOLDER + "_Test_3"; - static final String ALICEFOLDER_4 = ALICEFOLDER + "_Test_4"; - - static final String FORMAT = "TestFormat"; - static final String URI = "test/anURI"; - static final String MESSAGE = "testmessage"; - - @Test - public void removeChannel() throws IOException, ASAPException { - String testFolder = ALICEFOLDER_0; - - FSUtils.removeFolder(testFolder); - ASAPEngine storage = - ASAPEngineFS.getASAPStorage( - TestConstants.ALICE_NAME, testFolder, FORMAT); - - // fill it - storage.add(URI, MESSAGE); - storage.newEra(); - storage.add(URI, MESSAGE); - - ASAPChannel channel = storage.getChannel(URI); - Assert.assertEquals(2, channel.getMessages().size()); - - // remove it - storage.removeChannel(URI); - - // must be empty now - //channel = storage.getChannel(URI); - Assert.assertEquals(0, channel.getMessages().size()); - } - - @Test - public void channelTest() throws IOException, ASAPException { - String testFolder = ALICEFOLDER_1; - - byte[] bobMessageContent1 = new byte[] {0}; - byte[] aliceMessageContent1 = new byte[] {1}; - byte[] claraMessageContent1 = new byte[] {2}; - byte[] bobMessageContent2 = new byte[] {3}; - byte[] aliceMessageContent2 = new byte[] {4}; - byte[] claraMessageContent2 = new byte[] {5}; - - FSUtils.removeFolder(testFolder); - - ASAPEngineFS storage = (ASAPEngineFS) ASAPEngineFS.getASAPStorage(TestConstants.ALICE_NAME, testFolder, FORMAT); - storage.add(URI, aliceMessageContent1); - storage.add(URI, aliceMessageContent2); - - ASAPStorage bobStorage = storage.getIncomingStorage(TestConstants.BOB_NAME); - bobStorage.add(URI, bobMessageContent1); - bobStorage.add(URI, bobMessageContent2); - - ASAPStorage claraStorage = storage.getIncomingStorage(TestConstants.CLARA_NAME); - claraStorage.add(URI, claraMessageContent1); - claraStorage.add(URI, claraMessageContent2); - - ASAPMessages messages = storage.getChannel(URI).getMessages(new ASAPMessageCompare() { - @Override - public boolean earlier(byte[] messageA, byte[] messageB) { - return messageA[0] < messageB[0]; - } - }); - - Iterator messageIter = messages.getMessages(); - - messages.getMessage(5, true); - - - byte expected = 0; - while(messageIter.hasNext()) { - System.out.print(", " + expected); - if(expected == 4) { - int i = 42; // debug breakpoint - } - byte[] msg = messageIter.next(); - Assert.assertEquals(expected, msg[0]); - expected++; - } - } - - @Test - public void channelTest2() throws IOException, ASAPException { - String testFolder = ALICEFOLDER_2; - - byte[] aliceMessageContent1 = new byte[] {0}; - - FSUtils.removeFolder(testFolder); - - ASAPEngineFS storage = (ASAPEngineFS) ASAPEngineFS.getASAPStorage(TestConstants.ALICE_NAME, testFolder, FORMAT); - storage.add(URI, aliceMessageContent1); - ASAPMessages messages = storage.getChannel(URI).getMessages(false); - - Iterator messageIter = messages.getMessages(); - byte expected = 0; - while(messageIter.hasNext()) { - byte[] msg = messageIter.next(); - Assert.assertEquals(expected, msg[0]); - expected++; - } - } - - @Test - public void channelTest3() throws IOException, ASAPException { - String testFolder = ALICEFOLDER_3; - - byte[] bobMessageContent1 = new byte[] {0}; - byte[] bobMessageContent2 = new byte[] {1}; - byte[] claraMessageContent1 = new byte[] {2}; - byte[] claraMessageContent2 = new byte[] {3}; - byte[] aliceMessageContent1 = new byte[] {4}; - byte[] aliceMessageContent2 = new byte[] {5}; - - FSUtils.removeFolder(testFolder); - - ASAPEngineFS storage = (ASAPEngineFS) ASAPEngineFS.getASAPStorage(TestConstants.ALICE_NAME, testFolder, FORMAT); - storage.add(URI, aliceMessageContent1); - storage.add(URI, aliceMessageContent2); - - ASAPStorage bobStorage = storage.getIncomingStorage(TestConstants.BOB_NAME); - bobStorage.add(URI, bobMessageContent1); - bobStorage.add(URI, bobMessageContent2); - - ASAPStorage claraStorage = storage.getIncomingStorage(TestConstants.CLARA_NAME); - claraStorage.add(URI, claraMessageContent1); - claraStorage.add(URI, claraMessageContent2); - - ASAPMessages messages = storage.getChannel(URI).getMessages(new ASAPMessageCompare() { - @Override - public boolean earlier(byte[] messageA, byte[] messageB) { - return messageA[0] < messageB[0]; - } - }); - - Iterator messageIter = messages.getMessages(); - - messages.getMessage(5, true); - - byte expected = 0; - while(messageIter.hasNext()) { - System.out.print(", " + expected); - if(expected == 4) { - int i = 42; // debug breakpoint - } - byte[] msg = messageIter.next(); - Assert.assertEquals(expected, msg[0]); - expected++; - } - } - - @Test - public void channelTest4() throws IOException, ASAPException { - String testFolder = ALICEFOLDER_4; - - byte[] aliceMessageContent1 = new byte[] {0}; - byte[] aliceMessageContent2 = new byte[] {1}; - byte[] bobMessageContent1 = new byte[] {2}; - byte[] bobMessageContent2 = new byte[] {3}; - byte[] claraMessageContent1 = new byte[] {4}; - byte[] claraMessageContent2 = new byte[] {5}; - - FSUtils.removeFolder(testFolder); - - ASAPEngineFS storage = (ASAPEngineFS) ASAPEngineFS.getASAPStorage(TestConstants.ALICE_NAME, testFolder, FORMAT); - storage.add(URI, aliceMessageContent1); - storage.add(URI, aliceMessageContent2); - - ASAPStorage bobStorage = storage.getIncomingStorage(TestConstants.BOB_NAME); - bobStorage.add(URI, bobMessageContent1); - bobStorage.add(URI, bobMessageContent2); - - ASAPStorage claraStorage = storage.getIncomingStorage(TestConstants.CLARA_NAME); - claraStorage.add(URI, claraMessageContent1); - claraStorage.add(URI, claraMessageContent2); - - ASAPMessages messages = storage.getChannel(URI).getMessages(false); - - Assert.assertEquals(0, messages.getMessage(0, true)[0]); - Assert.assertEquals(1, messages.getMessage(1, true)[0]); - - byte[] msg = messages.getMessage(2, true); - Assert.assertTrue(msg[0] == 2 || msg[0] == 4); // comes from B or C - msg = messages.getMessage(3, true); - Assert.assertTrue(msg[0] == 3 || msg[0] == 5); // comes from B or C - msg = messages.getMessage(4, true); - Assert.assertTrue(msg[0] == 2 || msg[0] == 4); // comes from B or C - msg = messages.getMessage(5, true); - Assert.assertTrue(msg[0] == 3 || msg[0] == 5); // comes from B or C - } -} diff --git a/src/test/java/net/sharksystem/streams/DataExchangeTester.java b/src/test/java/net/sharksystem/streams/DataExchangeTester.java deleted file mode 100644 index 823f9c6..0000000 --- a/src/test/java/net/sharksystem/streams/DataExchangeTester.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.sharksystem.streams; - -import net.sharksystem.asap.ASAPException; -import net.sharksystem.asap.utils.ASAPSerialization; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -class DataExchangeTester implements Runnable { - private final InputStream is; - private final OutputStream os; - private final String id; - private int rounds; - public boolean synced = false; - - DataExchangeTester(InputStream is, OutputStream os, int rounds, String id) { - this.is = is; - this.os = os; - this.rounds = rounds; - this.id = id; - } - - @Override - public void run() { - // exchange some example data - int value = 0; - try { - int maxValue = this.rounds - 1; - System.out.println("Data Exchange Tester - count up to " + maxValue + " | " + id); - while (this.rounds-- > 0) { - System.out.println("write data: " + value + " | " + id); - ASAPSerialization.writeIntegerParameter(value, this.os); - int retVal = ASAPSerialization.readIntegerParameter(this.is); - System.out.println("read data: " + retVal + " | " + id); - - if (value != retVal) { - System.out.println("data exchange testers are out of sync: " + id); - break; - } - value++; - } - System.out.println("synced: " + id); - this.synced = true; - // block - System.out.println("read again - blocking (?): " + id); - int retVal = this.is.read(); - System.out.println("back from read after synced: " + retVal + " | " + id); - } catch (IOException | ASAPException e) { - System.out.println("exception data exchange tester - most probably good: " + id + " | " - + e.getLocalizedMessage()); - } - } -} diff --git a/src/test/java/net/sharksystem/streams/E2EStreamPairLinkTestVersion2.java b/src/test/java/net/sharksystem/streams/E2EStreamPairLinkTestVersion2.java deleted file mode 100644 index 8c77a34..0000000 --- a/src/test/java/net/sharksystem/streams/E2EStreamPairLinkTestVersion2.java +++ /dev/null @@ -1,218 +0,0 @@ -package net.sharksystem.streams; - -import net.sharksystem.utils.streams.StreamPair; -import net.sharksystem.utils.streams.StreamPairLink; -import net.sharksystem.utils.streams.StreamPairWrapper; -import net.sharksystem.utils.streams.WrappedStreamPairListener; -import net.sharksystem.utils.tcp.SocketFactory; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.HashMap; -import java.util.Map; - -public class E2EStreamPairLinkTestVersion2 { - - private static int portnumber = 7777; - - private static int getPortNumber() { - return E2EStreamPairLinkTestVersion2.portnumber++; - } - - /** - * Rebuild connection like in HubGeneric - * @throws IOException - * @throws InterruptedException - */ - @Test - public void streamPairStreamLinkTest() throws IOException, InterruptedException { - - WrappedStreamPairListenerDummy streamPairListenerDummy = new WrappedStreamPairListenerDummy(); - - //////////////////////// ALICE CONNECTOR - /* side Alice: peer side < ---- > connector side */ - int port = getPortNumber(); - SocketFactory socketFactory = new SocketFactory(new ServerSocket(port)); - (new Thread(socketFactory)).start(); - Thread.sleep(100); // give it a moment to start - - Socket socket1 = new Socket("localhost", port); - InputStream connectorPeerSideA_IS = socket1.getInputStream(); - OutputStream connectorPeerSideA_OS = socket1.getOutputStream(); - StreamPairWrapper streamPairConnectorPeerSideAlice = - new StreamPairWrapper(connectorPeerSideA_IS, connectorPeerSideA_OS, - streamPairListenerDummy, TestConstants.ALICE_ID + "(peer side)"); - - InputStream connectorHubSideA_IS = socketFactory.getInputStream(); - OutputStream connectorHubSideA_OS = socketFactory.getOutputStream(); - StreamPairWrapper streamPairConnectorHubSideAlice = - new StreamPairWrapper(connectorHubSideA_IS, connectorHubSideA_OS, - streamPairListenerDummy, TestConstants.ALICE_ID + "(hub side)"); - - //////////////////////// BOB CONNECTOR - /* side Bob: peer side < ---- > connector side */ - port = getPortNumber(); - socketFactory = new SocketFactory(new ServerSocket(port)); - (new Thread(socketFactory)).start(); - Thread.sleep(100); // give it a moment to start - - socket1 = new Socket("localhost", port); - InputStream connectorPeerSideB_IS = socket1.getInputStream(); - OutputStream connectorPeerSideB_OS = socket1.getOutputStream(); - StreamPairWrapper streamPairConnectorPeerSideBob = - new StreamPairWrapper(connectorPeerSideB_IS, connectorPeerSideB_OS, - streamPairListenerDummy, TestConstants.BOB_ID + "(peer side)"); - - InputStream connectorHubSideB_IS = socketFactory.getInputStream(); - OutputStream connectorHubSideB_OS = socketFactory.getOutputStream(); - StreamPairWrapper streamPairConnectorHubSideBob = - new StreamPairWrapper(connectorHubSideB_IS, connectorHubSideB_OS, - streamPairListenerDummy, TestConstants.BOB_ID + "(hub side)"); - - //////////////////////// LINK CONNECTOR HUB SIDE - StreamPairLink dataLink = - new StreamPairLink( - streamPairConnectorHubSideAlice, TestConstants.ALICE_ID, - streamPairConnectorHubSideBob, TestConstants.BOB_ID); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - // run End-to-End data session // - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - // simulate protocol - System.out.println("+++++++++++++++++ simulate protocol ++++++++++++++++++"); - int rounds = 5; - - // peer side Alice - DataExchangeTester aliceDataSession = - new DataExchangeTester( - streamPairConnectorPeerSideAlice.getInputStream(), - streamPairConnectorPeerSideAlice.getOutputStream(), - rounds, TestConstants.ALICE_ID); - - // peer side Bob - DataExchangeTester bobDataSession = - new DataExchangeTester( - streamPairConnectorPeerSideBob.getInputStream(), - streamPairConnectorPeerSideBob.getOutputStream(), - rounds, TestConstants.BOB_ID); - - Thread aliceDataSessionThread = new Thread(aliceDataSession); - Thread bobDataSessionThread = new Thread(bobDataSession); - - aliceDataSessionThread.start(); - bobDataSessionThread.start(); - - // wait a moment - Thread.sleep(1000); - Assert.assertTrue(aliceDataSession.synced); - Assert.assertTrue(bobDataSession.synced); - System.out.println(streamPairListenerDummy); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - // simulate data session time out // - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - streamPairConnectorPeerSideAlice.close(); - streamPairConnectorPeerSideBob.close(); - streamPairConnectorHubSideAlice.close(); - streamPairConnectorHubSideBob.close(); - - // wait a moment - System.out.flush(); - Thread.sleep(1000); - - System.out.println("available (Alice (peer)): " + connectorPeerSideA_IS.available()); - System.out.println("available (Alice (hub)): " + connectorHubSideA_IS.available()); - System.out.println("available (Bob (peer)): " + connectorPeerSideB_IS.available()); - System.out.println("available (Bob (hub)): " + connectorHubSideB_IS.available()); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - // run communication over non wrapped streams // - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - System.out.println("******************** ALICE CONNECTOR STILL ALIVE? ********************"); - // connector streams still intact? run session on non wrapped connections - // Alice - DataExchangeTester peerSide = - new DataExchangeTester( - connectorPeerSideA_IS, connectorPeerSideA_OS, - rounds, TestConstants.ALICE_ID + "(peer)"); - DataExchangeTester hubSide = - new DataExchangeTester( - connectorHubSideA_IS, connectorHubSideA_OS, - rounds, TestConstants.ALICE_ID + "(hub)"); - - Thread peerDataSessionThread = new Thread(peerSide); - Thread hubDataSessionThread = new Thread(hubSide); - - peerDataSessionThread.start(); - hubDataSessionThread.start(); - - // wait a moment - Thread.sleep(1000); - Assert.assertTrue(peerSide.synced); - Assert.assertTrue(hubSide.synced); - - System.out.println("******************** BOB CONNECTOR STILL ALIVE? ********************"); - peerSide = new DataExchangeTester( - connectorPeerSideB_IS, connectorPeerSideB_OS, - rounds, TestConstants.BOB_ID + "(peer)"); - hubSide = new DataExchangeTester( - connectorHubSideB_IS, connectorHubSideB_OS, - rounds, TestConstants.BOB_ID + "(hub)"); - - peerDataSessionThread = new Thread(peerSide); - hubDataSessionThread = new Thread(hubSide); - - peerDataSessionThread.start(); - hubDataSessionThread.start(); - - // wait a moment - Thread.sleep(1000); - Assert.assertTrue(peerSide.synced); - Assert.assertTrue(hubSide.synced); - } - - class WrappedStreamPairListenerDummy implements WrappedStreamPairListener { - public Map actions = new HashMap<>(); - - @Override - public void notifyClosed(StreamPair closedStreamPair, String key) { - System.out.println("closed: " + key); - } - - @Override - public void notifyAction(String key) { - int newCounter = 0; - Integer counter = this.actions.get(key); - if(counter != null) { - newCounter = counter; - } - newCounter++; - this.actions.put(key, newCounter); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - - if(this.actions.isEmpty()) { - sb.append("empty"); - } else { - for(String key : this.actions.keySet()) { - sb.append("actions("); - sb.append(key); - sb.append("): "); - sb.append(this.actions.get(key)); - sb.append("\n"); - } - } - - return sb.toString(); - } - } -} diff --git a/src/test/java/net/sharksystem/streams/TestConstants.java b/src/test/java/net/sharksystem/streams/TestConstants.java deleted file mode 100644 index 965d18d..0000000 --- a/src/test/java/net/sharksystem/streams/TestConstants.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sharksystem.streams; - -public interface TestConstants { - String ROOT_DIRECTORY = "playground/"; - String ALICE_ID = "ALICE"; - String ALICE_NAME = "Alice"; - String BOB_ID = "BOB"; - String BOB_NAME = "Bob"; - String CLARA_ID = "44"; - String CLARA_NAME = "Clara"; - String DAVID_ID = "45"; - String DAVID_NAME = "David"; - int DEFAULT_PORT = 7777; - - int maxTimeInSeconds = 1; -} diff --git a/src/test/java/net/sharksystem/testsupport/StoreReceivedMessages.java b/src/test/java/net/sharksystem/testsupport/StoreReceivedMessages.java deleted file mode 100644 index 760f108..0000000 --- a/src/test/java/net/sharksystem/testsupport/StoreReceivedMessages.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.sharksystem.testsupport; - -import net.sharksystem.asap.ASAPHop; -import net.sharksystem.asap.ASAPMessageReceivedListener; -import net.sharksystem.asap.ASAPMessages; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class StoreReceivedMessages implements ASAPMessageReceivedListener { - public List messageList = new ArrayList<>(); - @Override - public void asapMessagesReceived(ASAPMessages messages, String senderE2E, List asapHops) throws IOException { - this.messageList.add(messages); - } -}