This repository has been archived by the owner on Jun 1, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce Local SPSP Stream Receiver Link (#426)
* Fixes 415 to add support for an in-memory Stateless Stream Receiver Link. This enables a Connector to fulfill ILP packets without having to forward to an actual SPSP Receiver server. * Fix javadoc * Add ping packet to emitters * Update library current version * Fix unit tests Signed-off-by: David Fuelling <sappenin@gmail.com>
- Loading branch information
Showing
11 changed files
with
525 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<groupId>org.interledger</groupId> | ||
<artifactId>link-parent</artifactId> | ||
<version>HEAD-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<name>Quilt :: Link :: Stateless SPSP Receiver</name> | ||
<artifactId>link-stateless-spsp-receiver</artifactId> | ||
<description>A Link implementation for a stateless SPSP receiver.</description> | ||
<packaging>jar</packaging> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>codecs-framework</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>ilp-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>link-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>stream-receiver</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.auth0</groupId> | ||
<artifactId>java-jwt</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.fasterxml.jackson.core</groupId> | ||
<artifactId>jackson-databind</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.squareup.okhttp3</groupId> | ||
<artifactId>okhttp</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.immutables</groupId> | ||
<artifactId>value</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.zalando</groupId> | ||
<artifactId>problem</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
78 changes: 78 additions & 0 deletions
78
...less-spsp-receiver/src/main/java/org/interledger/link/spsp/StatelessSpspReceiverLink.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.interledger.link.spsp; | ||
|
||
import org.interledger.core.InterledgerAddress; | ||
import org.interledger.core.InterledgerPreparePacket; | ||
import org.interledger.core.InterledgerResponsePacket; | ||
import org.interledger.link.AbstractLink; | ||
import org.interledger.link.Link; | ||
import org.interledger.link.LinkHandler; | ||
import org.interledger.link.LinkType; | ||
import org.interledger.link.exceptions.LinkHandlerAlreadyRegisteredException; | ||
import org.interledger.stream.Denomination; | ||
import org.interledger.stream.receiver.StreamReceiver; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* <p>A {@link Link} that attempts to fulfill packets using an SPSP receiver.</p> | ||
*/ | ||
public class StatelessSpspReceiverLink extends AbstractLink<StatelessSpspReceiverLinkSettings> | ||
implements Link<StatelessSpspReceiverLinkSettings> { | ||
|
||
public static final String LINK_TYPE_STRING = "STATELESS_SPSP_RECEIVER"; | ||
public static final LinkType LINK_TYPE = LinkType.of(LINK_TYPE_STRING); | ||
|
||
private final StreamReceiver streamReceiver; | ||
private final Denomination denomination; | ||
|
||
/** | ||
* Required-Args Constructor. | ||
* | ||
* @param operatorAddressSupplier A supplier for the ILP address of this node operating this Link. This value may be | ||
* uninitialized, for example, in cases where the Link obtains its address from a | ||
* parent node using IL-DCP. If an ILP address has not been assigned, or it has not | ||
* been obtained via IL-DCP, then this value will by default be {@link Link#SELF}. | ||
* @param linkSettings A {@link StatelessSpspReceiverLinkSettings} for this Link. | ||
* @param streamReceiver A {@link StreamReceiver} that can fulfill packets. | ||
*/ | ||
public StatelessSpspReceiverLink( | ||
final Supplier<InterledgerAddress> operatorAddressSupplier, | ||
final StatelessSpspReceiverLinkSettings linkSettings, | ||
final StreamReceiver streamReceiver | ||
) { | ||
super(operatorAddressSupplier, linkSettings); | ||
this.denomination = Denomination.builder() | ||
.assetCode(linkSettings.assetCode()) | ||
.assetScale((short) linkSettings.assetScale()) | ||
.build(); | ||
this.streamReceiver = Objects.requireNonNull(streamReceiver); | ||
} | ||
|
||
@Override | ||
public void registerLinkHandler(final LinkHandler ilpDataHandler) throws LinkHandlerAlreadyRegisteredException { | ||
throw new RuntimeException( | ||
"StatelessSpspReceiver links never emit data, and thus should not have a registered DataHandler." | ||
); | ||
} | ||
|
||
@Override | ||
public InterledgerResponsePacket sendPacket(final InterledgerPreparePacket preparePacket) { | ||
Objects.requireNonNull(preparePacket, "preparePacket must not be null"); | ||
|
||
return streamReceiver.receiveMoney(preparePacket, this.getOperatorAddressSupplier().get(), this.denomination) | ||
.map(fulfillPacket -> { | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("Packet fulfilled! preparePacket={} fulfillPacket={}", preparePacket, fulfillPacket); | ||
} | ||
return fulfillPacket; | ||
}, | ||
rejectPacket -> { | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("Packet rejected! preparePacket={} rejectPacket={}", preparePacket, rejectPacket); | ||
} | ||
return rejectPacket; | ||
} | ||
); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...sp-receiver/src/main/java/org/interledger/link/spsp/StatelessSpspReceiverLinkFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package org.interledger.link.spsp; | ||
|
||
import org.interledger.core.InterledgerAddress; | ||
import org.interledger.link.Link; | ||
import org.interledger.link.LinkFactory; | ||
import org.interledger.link.LinkId; | ||
import org.interledger.link.LinkSettings; | ||
import org.interledger.link.LinkType; | ||
import org.interledger.link.PacketRejector; | ||
import org.interledger.link.exceptions.LinkException; | ||
import org.interledger.stream.receiver.StatelessStreamReceiver; | ||
|
||
import com.google.common.base.Preconditions; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* An implementation of {@link LinkFactory} for constructing instances of {@link StatelessSpspReceiverLink}. | ||
*/ | ||
public class StatelessSpspReceiverLinkFactory implements LinkFactory { | ||
|
||
private final PacketRejector packetRejector; | ||
private final StatelessStreamReceiver statelessStreamReceiver; | ||
|
||
/** | ||
* Required-args Constructor. | ||
* | ||
* @param packetRejector An instance of {@link PacketRejector}. | ||
* @param statelessStreamReceiver A {@link StatelessStreamReceiver} for encrypting/decrypting STREAM packets. | ||
*/ | ||
public StatelessSpspReceiverLinkFactory( | ||
final PacketRejector packetRejector, final StatelessStreamReceiver statelessStreamReceiver | ||
) { | ||
this.packetRejector = Objects.requireNonNull(packetRejector, "packetRejector must not be null"); | ||
this.statelessStreamReceiver = Objects | ||
.requireNonNull(statelessStreamReceiver, "statelessStreamReceiver must not be null"); | ||
} | ||
|
||
|
||
@Override | ||
public Link<?> constructLink( | ||
final Supplier<InterledgerAddress> operatorAddressSupplier, final LinkSettings linkSettings | ||
) { | ||
Objects.requireNonNull(operatorAddressSupplier, "operatorAddressSupplier must not be null"); | ||
Objects.requireNonNull(linkSettings, "linkSettings must not be null"); | ||
|
||
if (!this.supports(linkSettings.getLinkType())) { | ||
throw new LinkException( | ||
String.format("LinkType not supported by this factory. linkType=%s", linkSettings.getLinkType()), | ||
LinkId.of("n/a") | ||
); | ||
} | ||
|
||
Preconditions.checkArgument( | ||
StatelessSpspReceiverLinkSettings.class.isAssignableFrom(linkSettings.getClass()), | ||
"Constructing an instance of StatelessSpspReceiverLink requires an instance of StatelessSpspReceiverLinkSettings" | ||
); | ||
|
||
return new StatelessSpspReceiverLink( | ||
operatorAddressSupplier, (StatelessSpspReceiverLinkSettings) linkSettings, statelessStreamReceiver | ||
); | ||
} | ||
|
||
@Override | ||
public boolean supports(LinkType linkType) { | ||
return StatelessSpspReceiverLink.LINK_TYPE.equals(linkType); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
...p-receiver/src/main/java/org/interledger/link/spsp/StatelessSpspReceiverLinkSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.interledger.link.spsp; | ||
|
||
import org.interledger.link.LinkSettings; | ||
import org.interledger.link.LinkType; | ||
|
||
import org.immutables.value.Value; | ||
import org.immutables.value.Value.Derived; | ||
|
||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* An extension of {@link LinkSettings} for Stateless SPSP receiver links. | ||
*/ | ||
public interface StatelessSpspReceiverLinkSettings extends LinkSettings { | ||
|
||
static ImmutableStatelessSpspReceiverLinkSettings.Builder builder() { | ||
return ImmutableStatelessSpspReceiverLinkSettings.builder(); | ||
} | ||
|
||
@Override | ||
default LinkType getLinkType() { | ||
return StatelessSpspReceiverLink.LINK_TYPE; | ||
} | ||
|
||
/** | ||
* Currency code or other asset identifier that will be used to select the correct rate for this account. | ||
*/ | ||
String assetCode(); | ||
|
||
/** | ||
* Interledger amounts are integers, but most currencies are typically represented as # fractional units, e.g. cents. | ||
* This property defines how many Interledger units make # up one regular unit. For dollars, this would usually be set | ||
* to 9, so that Interledger # amounts are expressed in nano-dollars. | ||
* | ||
* @return an int representing this account's asset scale. | ||
*/ | ||
int assetScale(); | ||
|
||
@Value.Immutable | ||
abstract class AbstractStatelessSpspReceiverLinkSettings implements StatelessSpspReceiverLinkSettings { | ||
|
||
@Derived | ||
@Override | ||
public LinkType getLinkType() { | ||
return StatelessSpspReceiverLink.LINK_TYPE; | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.