Search in sources :

Example 16 with PartyInfo

use of com.quorum.tessera.partyinfo.model.PartyInfo in project tessera by ConsenSys.

the class PartyInfoResourceTest method partyInfo.

@Test
public void partyInfo() {
    String url = "http://www.bogus.com";
    PublicKey myKey = PublicKey.from("myKey".getBytes());
    PublicKey recipientKey = PublicKey.from("recipientKey".getBytes());
    String message = "I love sparrows";
    byte[] payload = message.getBytes();
    Recipient recipient = Recipient.of(recipientKey, url);
    Set<Recipient> recipientList = Collections.singleton(recipient);
    PartyInfo partyInfo = new PartyInfo(url, recipientList, Collections.emptySet());
    when(partyInfoParser.from(payload)).thenReturn(partyInfo);
    when(enclave.defaultPublicKey()).thenReturn(myKey);
    when(partyInfoParser.to(partyInfo)).thenReturn(payload);
    EncodedPayload encodedPayload = mock(EncodedPayload.class);
    List<String> uuidList = new ArrayList<>();
    doAnswer((invocation) -> {
        byte[] d = invocation.getArgument(0);
        uuidList.add(new String(d));
        return encodedPayload;
    }).when(enclave).encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
    when(payloadEncoder.encode(encodedPayload)).thenReturn(payload);
    WebTarget webTarget = mock(WebTarget.class);
    when(restClient.target(url)).thenReturn(webTarget);
    when(webTarget.path(anyString())).thenReturn(webTarget);
    Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
    when(webTarget.request()).thenReturn(invocationBuilder);
    Response response = mock(Response.class);
    when(response.getStatus()).thenReturn(200);
    doAnswer((invocation) -> uuidList.get(0)).when(response).readEntity(String.class);
    when(invocationBuilder.post(any(Entity.class))).thenReturn(response);
    Response result = partyInfoResource.partyInfo(payload, List.of("v1,v2"));
    assertThat(result.getStatus()).isEqualTo(200);
    verify(partyInfoParser).from(payload);
    verify(enclave).defaultPublicKey();
    verify(enclave).encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
    verify(payloadEncoder).encode(encodedPayload);
    verify(restClient).target(url);
    ArgumentCaptor<NodeInfo> argCaptor = ArgumentCaptor.forClass(NodeInfo.class);
    verify(discovery).onUpdate(argCaptor.capture());
    final NodeInfo nodeInfo = argCaptor.getValue();
    assertThat(nodeInfo).isNotNull();
    assertThat(nodeInfo.getUrl()).isEqualTo(url);
    assertThat(nodeInfo.supportedApiVersions()).containsExactlyInAnyOrder("v1", "v2");
}
Also used : Entity(jakarta.ws.rs.client.Entity) Invocation(jakarta.ws.rs.client.Invocation) PublicKey(com.quorum.tessera.encryption.PublicKey) Recipient(com.quorum.tessera.partyinfo.model.Recipient) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo) Response(jakarta.ws.rs.core.Response) PrivacyMetadata(com.quorum.tessera.enclave.PrivacyMetadata) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) WebTarget(jakarta.ws.rs.client.WebTarget) Test(org.junit.Test)

Example 17 with PartyInfo

use of com.quorum.tessera.partyinfo.model.PartyInfo in project tessera by ConsenSys.

the class PartyInfoResourceTest method partyInfoExceptionIfValidationFailsWith200.

@Test
public void partyInfoExceptionIfValidationFailsWith200() {
    final int validateResponseCode = 200;
    final String validateResponseMsg = "BADRESPONSE";
    String url = "http://www.bogus.com";
    PublicKey myKey = PublicKey.from("myKey".getBytes());
    PublicKey recipientKey = PublicKey.from("recipientKey".getBytes());
    String message = "I love sparrows";
    byte[] payload = message.getBytes();
    Recipient recipient = Recipient.of(recipientKey, url);
    Set<Recipient> recipientList = Collections.singleton(recipient);
    PartyInfo partyInfo = new PartyInfo(url, recipientList, Collections.emptySet());
    when(partyInfoParser.from(payload)).thenReturn(partyInfo);
    when(enclave.defaultPublicKey()).thenReturn(myKey);
    when(partyInfoParser.to(partyInfo)).thenReturn(payload);
    EncodedPayload encodedPayload = mock(EncodedPayload.class);
    when(enclave.encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class))).thenReturn(encodedPayload);
    when(payloadEncoder.encode(encodedPayload)).thenReturn(payload);
    WebTarget webTarget = mock(WebTarget.class);
    when(restClient.target(url)).thenReturn(webTarget);
    when(webTarget.path(anyString())).thenReturn(webTarget);
    Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
    when(webTarget.request()).thenReturn(invocationBuilder);
    Response response = mock(Response.class);
    when(response.getStatus()).thenReturn(validateResponseCode);
    doAnswer((invocation) -> validateResponseMsg).when(response).readEntity(String.class);
    when(invocationBuilder.post(any(Entity.class))).thenReturn(response);
    try {
        partyInfoResource.partyInfo(payload, Collections.emptyList());
        failBecauseExceptionWasNotThrown(SecurityException.class);
    } catch (SecurityException ex) {
        verify(partyInfoParser).from(payload);
        verify(enclave).defaultPublicKey();
        verify(enclave).encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
        verify(payloadEncoder).encode(encodedPayload);
        verify(restClient).target(url);
    }
}
Also used : Entity(jakarta.ws.rs.client.Entity) Invocation(jakarta.ws.rs.client.Invocation) PublicKey(com.quorum.tessera.encryption.PublicKey) Recipient(com.quorum.tessera.partyinfo.model.Recipient) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo) Response(jakarta.ws.rs.core.Response) PrivacyMetadata(com.quorum.tessera.enclave.PrivacyMetadata) WebTarget(jakarta.ws.rs.client.WebTarget) Test(org.junit.Test)

Example 18 with PartyInfo

use of com.quorum.tessera.partyinfo.model.PartyInfo in project tessera by ConsenSys.

the class PartyInfoBroadcasterTest method exceptionThrowByPostDoesntBubble.

@Test
public void exceptionThrowByPostDoesntBubble() {
    final NodeInfo partyInfo = NodeInfo.Builder.create().withUrl(OWN_URL).build();
    when(partyStore.getParties()).thenReturn(Set.of(URI.create(TARGET_URL), URI.create(TARGET_URL_2)));
    doReturn(partyInfo).when(discovery).getCurrent();
    doThrow(UnsupportedOperationException.class).when(p2pClient).sendPartyInfo(TARGET_URL, DATA);
    final Throwable throwable = catchThrowable(partyInfoBroadcaster::run);
    assertThat(throwable).isNull();
    verify(partyStore).loadFromConfigIfEmpty();
    verify(partyStore).getParties();
    verify(p2pClient).sendPartyInfo(TARGET_URL, DATA);
    verify(p2pClient).sendPartyInfo(TARGET_URL_2, DATA);
    verify(discovery).getCurrent();
    verify(partyInfoParser).to(any(PartyInfo.class));
}
Also used : NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) Assertions.catchThrowable(org.assertj.core.api.Assertions.catchThrowable) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo) Test(org.junit.Test)

Example 19 with PartyInfo

use of com.quorum.tessera.partyinfo.model.PartyInfo in project tessera by ConsenSys.

the class PartyInfoBroadcaster method run.

/**
 * Iterates over all known parties and contacts them for the current state of their known node
 * discovery list
 *
 * <p>For Tessera 0.9 backwards, after contacting the known parties, this poller then updates this
 * nodes list of data with any new information collected.
 *
 * <p>This behaviour is now deprecated since the /partyinfo API call now has been made more strict
 * with node validation to prevent exploiting the API to attack the Tessera network.
 *
 * <p>This call is merely to let its parties know about this node existence, any recipients that
 * want to be added to this node's PartyInfo will need to make their own partyinfo call and
 * validation
 */
@Override
public void run() {
    LOGGER.info("Started PartyInfo polling round");
    partyStore.loadFromConfigIfEmpty();
    final NodeInfo nodeInfo = discovery.getCurrent();
    final NodeUri ourUrl = NodeUri.create(nodeInfo.getUrl());
    final PartyInfo partyInfo = PartyInfoBuilder.create().withUri(nodeInfo.getUrl()).withRecipients(nodeInfo.getRecipientsAsMap()).build();
    final byte[] encodedPartyInfo = partyInfoParser.to(partyInfo);
    LOGGER.debug("Contacting following peers with PartyInfo: {}", partyInfo.getParties());
    LOGGER.debug("Sending party info {}", nodeInfo);
    partyStore.getParties().stream().map(NodeUri::create).filter(url -> !ourUrl.equals(url)).forEach(url -> pollSingleParty(url.asString(), encodedPartyInfo));
    LOGGER.info("Finished PartyInfo polling round");
}
Also used : Logger(org.slf4j.Logger) Executor(java.util.concurrent.Executor) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) NodeUri(com.quorum.tessera.discovery.NodeUri) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) Discovery(com.quorum.tessera.discovery.Discovery) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) ProcessingException(jakarta.ws.rs.ProcessingException) Optional(java.util.Optional) P2pClient(com.quorum.tessera.partyinfo.P2pClient) URI(java.net.URI) PartyInfoBuilder(com.quorum.tessera.partyinfo.model.PartyInfoBuilder) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) NodeUri(com.quorum.tessera.discovery.NodeUri) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo)

Example 20 with PartyInfo

use of com.quorum.tessera.partyinfo.model.PartyInfo in project tessera by ConsenSys.

the class SyncPoller method updatePartyInfo.

private boolean updatePartyInfo(String url) {
    try {
        final NodeInfo nodeInfo = discovery.getCurrent();
        final PartyInfo partyInfo = PartyInfoBuilder.create().withUri(nodeInfo.getUrl()).withRecipients(nodeInfo.getRecipientsAsMap()).build();
        LOGGER.debug("Sending node info {} to {}", nodeInfo, url);
        final byte[] encodedPartyInfo = partyInfoParser.to(partyInfo);
        // we deliberately discard the response as we do not want to fully duplicate the
        // PartyInfoPoller
        boolean outcome = p2pClient.sendPartyInfo(url, encodedPartyInfo);
        LOGGER.debug("Sent node info {} to {}", nodeInfo, url);
        return outcome;
    } catch (final Exception ex) {
        LOGGER.warn("Failed to connect to node {} for partyinfo, due to {}", url, ex.getMessage());
        LOGGER.debug(null, ex);
        return false;
    }
}
Also used : NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) PartyInfo(com.quorum.tessera.partyinfo.model.PartyInfo)

Aggregations

PartyInfo (com.quorum.tessera.partyinfo.model.PartyInfo)24 Test (org.junit.Test)18 Recipient (com.quorum.tessera.partyinfo.model.Recipient)16 PublicKey (com.quorum.tessera.encryption.PublicKey)14 Entity (jakarta.ws.rs.client.Entity)13 Response (jakarta.ws.rs.core.Response)13 NodeInfo (com.quorum.tessera.partyinfo.node.NodeInfo)11 PartyInfoParser (com.quorum.tessera.p2p.partyinfo.PartyInfoParser)9 Collectors (java.util.stream.Collectors)9 Client (jakarta.ws.rs.client.Client)8 MediaType (jakarta.ws.rs.core.MediaType)8 java.util (java.util)8 Party (com.quorum.tessera.partyinfo.model.Party)7 JsonObject (jakarta.json.JsonObject)7 Config (com.quorum.tessera.config.Config)6 EncryptorConfig (com.quorum.tessera.config.EncryptorConfig)6 ServerConfig (com.quorum.tessera.config.ServerConfig)6 ConfigKeyPair (com.quorum.tessera.config.keypairs.ConfigKeyPair)6 KeyEncryptor (com.quorum.tessera.config.keys.KeyEncryptor)6 KeyEncryptorFactory (com.quorum.tessera.config.keys.KeyEncryptorFactory)6