Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions at_client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<doclint>all,-missing</doclint>
</configuration>
</plugin>

<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public interface AtConnection {

String executeCommand(String command) throws IOException;

/**
* Represents something which can implement atprotocol authentication workflow
* by executing commands with a {@link AtConnection}
*/
interface Authenticator {
void authenticate(AtConnection connection) throws AtException, IOException;
}
Expand Down
13 changes: 12 additions & 1 deletion at_client/src/main/java/org/atsign/client/api/AtEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@
import java.util.Set;

/**
*
* Parent interface for related interfaces
*/
public interface AtEvents {

/**
* Represents something that will receive events
*/
interface AtEventListener {
void handleEvent(AtEventType eventType, Map<String, Object> eventData);
}

/**
* Represents something that can dispatch events to registered {@link AtEventListener}
*/
interface AtEventBus {
/**
* @param listener to handle various events which originate from Secondaries
Expand All @@ -26,6 +33,10 @@ interface AtEventBus {
int publishEvent(AtEventType eventType, Map<String, Object> eventData);

}

/**
* Different event types
*/
enum AtEventType {
// events which originate from the client's "Monitor" connection, which asynchronously
// receives notification events from its secondary server
Expand Down
52 changes: 32 additions & 20 deletions at_client/src/main/java/org/atsign/client/api/Secondary.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
* talks, via TLS over a secure socket, to the cloud Secondary server.
* <br>
* As we implement client-side offline storage, performance caching etc., we can expect e.g.
* <br/>
* AtClient -> FastCacheSecondary -> OfflineStorageSecondary -> RemoteSecondary<br/>
* <br>
* AtClient {@code ->} FastCacheSecondary {@code ->} OfflineStorageSecondary {@code ->}
* RemoteSecondary
* <br>
* where FastCacheSecondary might be an in-memory LRU cache, and OfflineStorageSecondary is a
* persistent cache of some or all of the information in the RemoteSecondary. To make this
* possible, each Secondary will need to be able to fully handle the @ protocol, thus the
Expand All @@ -41,6 +43,9 @@ public interface Secondary extends AtEvents.AtEventListener, Closeable {

boolean isMonitorRunning();

/**
* Used to hold the partially decoded response from a {@link Secondary}
*/
class Response {
private String rawDataResponse = null;
private String rawErrorResponse;
Expand Down Expand Up @@ -99,48 +104,51 @@ public AtException getException() {
if (!isError()) {
return null;
}
if ("AT0001".equals(errorCode)) {
if (AtServerRuntimeException.CODE.equals(errorCode)) {
return new AtServerRuntimeException(errorText);
} else if ("AT0003".equals(errorCode)) {
} else if (AtInvalidSyntaxException.CODE.equals(errorCode)) {
return new AtInvalidSyntaxException(errorText);
} else if ("AT0005".equals(errorCode)) {
} else if (AtBufferOverFlowException.CODE.equals(errorCode)) {
return new AtBufferOverFlowException(errorText);
} else if ("AT0006".equals(errorCode)) {
} else if (AtOutboundConnectionLimitException.CODE.equals(errorCode)) {
return new AtOutboundConnectionLimitException(errorText);
} else if ("AT0007".equals(errorCode)) {
} else if (AtSecondaryNotFoundException.CODE.equals(errorCode)) {
return new AtSecondaryNotFoundException(errorText);
} else if ("AT0008".equals(errorCode)) {
} else if (AtHandShakeException.CODE.equals(errorCode)) {
return new AtHandShakeException(errorText);
} else if ("AT0009".equals(errorCode)) {
} else if (AtUnauthorizedException.CODE.equals(errorCode)) {
return new AtUnauthorizedException(errorText);
} else if ("AT0010".equals(errorCode)) {
} else if (AtInternalServerError.CODE.equals(errorCode)) {
return new AtInternalServerError(errorText);
} else if ("AT0011".equals(errorCode)) {
} else if (AtInternalServerException.CODE.equals(errorCode)) {
return new AtInternalServerException(errorText);
} else if ("AT0012".equals(errorCode)) {
} else if (AtInboundConnectionLimitException.CODE.equals(errorCode)) {
return new AtInboundConnectionLimitException(errorText);
} else if ("AT0013".equals(errorCode)) {
} else if (AtBlockedConnectionException.CODE.equals(errorCode)) {
return new AtBlockedConnectionException(errorText);
} else if ("AT0015".equals(errorCode)) {
} else if (AtKeyNotFoundException.CODE.equals(errorCode)) {
return new AtKeyNotFoundException(errorText);
} else if ("AT0016".equals(errorCode)) {
} else if (AtInvalidAtKeyException.CODE.equals(errorCode)) {
return new AtInvalidAtKeyException(errorText);
} else if ("AT0021".equals(errorCode)) {
} else if (AtSecondaryConnectException.CODE.equals(errorCode)) {
return new AtSecondaryConnectException(errorText);
} else if ("AT0022".equals(errorCode)) {
} else if (AtIllegalArgumentException.CODE.equals(errorCode)) {
return new AtIllegalArgumentException(errorText);
} else if ("AT0023".equals(errorCode)) {
} else if (AtTimeoutException.CODE.equals(errorCode)) {
return new AtTimeoutException(errorText);
} else if ("AT0024".equals(errorCode)) {
} else if (AtServerIsPausedException.CODE.equals(errorCode)) {
return new AtServerIsPausedException(errorText);
} else if ("AT0401".equals(errorCode)) {
} else if (AtUnauthenticatedException.CODE.equals(errorCode)) {
return new AtUnauthenticatedException(errorText);
}

return new AtNewErrorCodeWhoDisException(errorCode, errorText);
}
}

/**
* Value class for hostname and port tuple
*/
class Address {
public final String host;
public final int port;
Expand Down Expand Up @@ -173,6 +181,10 @@ public String toString() {
}
}

/**
* Represents something that, given an {@link AtSign}, can resolve the {@link Address} of the
* {@link Secondary} for this {@link AtSign}
*/
interface AddressFinder {
Address findSecondary(AtSign atSign) throws IOException, AtSecondaryNotFoundException;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;

/**
* @see org.atsign.client.api.AtClient
* Implementation of an {@link AtClient} which wraps a {@link Secondary}
* in order to implement the "map like" features of the {@link AtClient} interface
*/
@SuppressWarnings({"RedundantThrows", "unused"})
@Slf4j
Expand Down Expand Up @@ -637,7 +638,7 @@ private List<AtKey> _getAtKeys(String regex, boolean fetchMetadata) throws AtExc
}
ResponseTransformers.ScanResponseTransformer scanResponseTransformer =
new ResponseTransformers.ScanResponseTransformer(AtClientImpl::isNotManagementKey);
List<String> rawArray = scanResponseTransformer.transform(scanRawResponse);
List<String> rawArray = scanResponseTransformer.apply(scanRawResponse);

List<AtKey> atKeys = new ArrayList<>();
for (String atKeyRaw : rawArray) { // eg atKeyRaw == @bob:phone@alice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
import org.atsign.common.AtException;

/**
* @see org.atsign.client.api.AtConnection
* Core implementation of an {@link AtConnection} which uses Java NIO. This
* class contains the implementation of the socket connect / disconnect,
* writing atprotocol commands and reading atprotocol responses.
* If the socket becomes disconnected then it will be re-connected as part
* of sending the next command.
*/
@Slf4j
public abstract class AtConnectionBase implements AtConnection {

private final String url;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;

/**
*
* A {@link AtMonitorConnection} represents a connection to an AtServer which,
* when started will send the atprotocol monitor command and then processes
* notifications and heartbeat messages until it is stopped. If the socket disconnects
* then it will be automatically reconnected.
*/
@Slf4j
public class AtMonitorConnection extends AtSecondaryConnection implements Runnable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import org.atsign.common.AtSign;

/**
* @see org.atsign.client.api.AtConnectionFactory
* Standard implementation of {@link AtConnectionFactory} for creating {@link AtSecondaryConnection}
* and {@link AtRootConnection} instances.
*/
public class DefaultAtConnectionFactory implements AtConnectionFactory {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import java.util.concurrent.Executors;

/**
*
* In memory implementation of {@link AtEventBus} which will asynchronously dispatch
* events to registered listeners.
*/
@Slf4j
public class SimpleAtEventBus implements AtEventBus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import org.atsign.common.exceptions.AtUnknownResponseException;

/**
* @see org.atsign.client.api.Secondary
* Implementation of {@link Secondary} wraps an {@link AtSecondaryConnection} and
* an {@link AtMonitorConnection}.
*/
@Slf4j
public class RemoteSecondary implements Secondary {
Expand Down
25 changes: 25 additions & 0 deletions at_client/src/main/java/org/atsign/client/cli/AbstractCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,37 @@
import picocli.CommandLine.ITypeConverter;
import picocli.CommandLine.Option;

/**
* Base class for Command Line Interface utilities. Holds common fields such as root server
* the {@link AtSign} which is connecting and the file which contains the {@link AtKeys}
*
* @param <T> used to provide fluent builder style API
*/
public abstract class AbstractCli<T extends AbstractCli<T>> {

/**
* models server response string which is non-empty JSON map
*/
protected static final Pattern DATA_JSON_NON_EMPTY_MAP = Pattern.compile("data:(\\{.+})");

/**
* models server response string which is JSON map
*/
protected static final Pattern DATA_JSON_MAP = Pattern.compile("data:(\\{.*})");

/**
* models server response string which is non-empty JSON list
*/
protected static final Pattern DATA_JSON_NO_EMPTY_LIST = Pattern.compile("data:(\\[.+])");

/**
* models server response string which is integer
*/
protected static final Pattern DATA_INT = Pattern.compile("data:\\d+");

/**
* models server response string containing no whitespace
*/
public static final Pattern DATA_NON_WHITESPACE = Pattern.compile("data:(\\S+)");

protected String rootUrl = "root.atsign.org";
Expand Down
4 changes: 4 additions & 0 deletions at_client/src/main/java/org/atsign/client/cli/DumpKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import org.atsign.client.util.KeysUtil;
import org.atsign.common.AtSign;

/**
* Utility which, given an {@link AtSign} will load {@link AtKeys} from the
* default location and dump the contents to stdout
*/
@Slf4j
public class DumpKeys {
public static void main(String[] args) throws Exception {
Expand Down
4 changes: 4 additions & 0 deletions at_client/src/main/java/org/atsign/client/util/ArgsUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import org.atsign.client.api.Secondary;
import org.atsign.client.api.impl.connections.AtRootConnection;

/**
* Utility class which contains a method for creating an
* {@link org.atsign.client.api.Secondary.AddressFinder}
*/
public class ArgsUtil {
public static Secondary.AddressFinder createAddressFinder(String rootUrl) {
Secondary.AddressFinder addressFinder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import org.atsign.common.exceptions.AtInvalidAtKeyException;
import org.atsign.common.exceptions.AtSecondaryConnectException;

/**
* Utility class with key string validation methods
*/
public class AtClientValidation {
// TODO Lots of atServer-address-finding going on here. Need a caching finder.
// TODO Change all of these static methods.
Expand Down
21 changes: 20 additions & 1 deletion at_client/src/main/java/org/atsign/client/util/AuthUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@
import org.atsign.common.exceptions.AtUnauthenticatedException;

/**
*
* Encapsulates Atsign Platform authentication command response workflows.
*/
public class AuthUtil {

/**
* Sends a from command followed by cram command.
*
* @param connection connection to an AtServer
* @param atSign the AtSign to authenticate
* @param cramSecret the secret with which to respond to the authentication challenge
* @throws AtException If the authentication fails
* @throws IOException Delegated from AtServer
*/
public void authenticateWithCram(AtSecondaryConnection connection, AtSign atSign, String cramSecret)
throws AtException, IOException {
String fromResponse = connection.executeCommand("from:" + atSign);
Expand All @@ -40,6 +50,15 @@ public void authenticateWithCram(AtSecondaryConnection connection, AtSign atSign
}
}

/**
* Sends a from command followed by a pkam command.
*
* @param connection connection to an AtServer
* @param atSign the AtSign to authenticate
* @param keys AtKeys which contains the PKAM private key and associated {@link EnrollmentId}
* @throws AtException If the authentication fails
* @throws IOException Delegated from AtServer
*/
public void authenticateWithPkam(AtConnection connection, AtSign atSign, AtKeys keys)
throws AtException, IOException {
if (!keys.hasPkamKeys()) {
Expand Down
5 changes: 4 additions & 1 deletion at_client/src/main/java/org/atsign/client/util/ByteUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

import java.nio.charset.StandardCharsets;

/**
* Utility class with "no throw" methods for converting between byte arrays and Strings
*/
@Slf4j
public class ByteUtil {
public static String convert(byte[] data) {
Expand All @@ -19,7 +22,7 @@ public static byte[] convert(String data) {
try {
return data.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
log.error("Error occured while parsing the string to byte array data", e);
log.error("Error occurred while parsing the string to byte array data", e);
return null;
}
}
Expand Down
3 changes: 3 additions & 0 deletions at_client/src/main/java/org/atsign/client/util/Constants.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.atsign.client.util;

/**
* Atsign Platform constants
*/
public final class Constants {
private Constants() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
* Utility class which registers bouncycastle as a security {@link Provider} and provides
* static methods for the various encryption functions required by Atsign client APIs
*/
public class EncryptionUtil {

public static final String SIGNING_ALGO_RSA = "rsa2048";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.atsign.client.util;

/**
* Identifier that represent a specific {@link org.atsign.common.AtSign} enrollment
* and association with a specific key pair used for authentication management (PKAM)
*/
public class EnrollmentId extends TypedString {

private EnrollmentId(String id) {
Expand Down
Loading
Loading