Search in sources :

Example 1 with SiteToSiteRestApiClient

use of org.apache.nifi.remote.util.SiteToSiteRestApiClient in project nifi by apache.

the class HttpClient method fetchRemotePeerStatuses.

@Override
public Set<PeerStatus> fetchRemotePeerStatuses(PeerDescription peerDescription) throws IOException {
    // Each node should has the same URL structure and network reach-ability with the proxy configuration.
    try (final SiteToSiteRestApiClient apiClient = new SiteToSiteRestApiClient(config.getSslContext(), config.getHttpProxy(), config.getEventReporter())) {
        final String scheme = peerDescription.isSecure() ? "https" : "http";
        apiClient.setBaseUrl(scheme, peerDescription.getHostname(), peerDescription.getPort());
        final int timeoutMillis = (int) config.getTimeout(TimeUnit.MILLISECONDS);
        apiClient.setConnectTimeoutMillis(timeoutMillis);
        apiClient.setReadTimeoutMillis(timeoutMillis);
        apiClient.setCacheExpirationMillis(config.getCacheExpiration(TimeUnit.MILLISECONDS));
        apiClient.setLocalAddress(config.getLocalAddress());
        final Collection<PeerDTO> peers = apiClient.getPeers();
        if (peers == null || peers.size() == 0) {
            throw new IOException("Couldn't get any peer to communicate with. " + apiClient.getBaseUrl() + " returned zero peers.");
        }
        // was added in NiFi 1.0.0, which means that peer-to-peer queries are always allowed.
        return peers.stream().map(p -> new PeerStatus(new PeerDescription(p.getHostname(), p.getPort(), p.isSecure()), p.getFlowFileCount(), true)).collect(Collectors.toSet());
    }
}
Also used : PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) LoggerFactory(org.slf4j.LoggerFactory) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) StringUtils(org.apache.commons.lang3.StringUtils) SiteToSiteClientConfig(org.apache.nifi.remote.client.SiteToSiteClientConfig) HashSet(java.util.HashSet) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) PeerStatus(org.apache.nifi.remote.PeerStatus) PeerStatusProvider(org.apache.nifi.remote.client.PeerStatusProvider) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) URI(java.net.URI) PeerSelector(org.apache.nifi.remote.client.PeerSelector) ThreadFactory(java.util.concurrent.ThreadFactory) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) AbstractSiteToSiteClient(org.apache.nifi.remote.client.AbstractSiteToSiteClient) TransferDirection(org.apache.nifi.remote.TransferDirection) Logger(org.slf4j.Logger) PeerDescription(org.apache.nifi.remote.PeerDescription) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) Collection(java.util.Collection) Set(java.util.Set) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Transaction(org.apache.nifi.remote.Transaction) Executors(java.util.concurrent.Executors) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) TimeUnit(java.util.concurrent.TimeUnit) HttpClientTransaction(org.apache.nifi.remote.protocol.http.HttpClientTransaction) PeerDTO(org.apache.nifi.web.api.dto.remote.PeerDTO) Peer(org.apache.nifi.remote.Peer) Collections(java.util.Collections) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) PeerDescription(org.apache.nifi.remote.PeerDescription) PeerStatus(org.apache.nifi.remote.PeerStatus) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) IOException(java.io.IOException) PeerDTO(org.apache.nifi.web.api.dto.remote.PeerDTO)

Example 2 with SiteToSiteRestApiClient

use of org.apache.nifi.remote.util.SiteToSiteRestApiClient in project nifi by apache.

the class HttpClient method createTransaction.

@Override
public Transaction createTransaction(final TransferDirection direction) throws HandshakeException, PortNotRunningException, ProtocolException, UnknownPortException, IOException {
    final int timeoutMillis = (int) config.getTimeout(TimeUnit.MILLISECONDS);
    PeerStatus peerStatus;
    while ((peerStatus = peerSelector.getNextPeerStatus(direction)) != null) {
        logger.debug("peerStatus={}", peerStatus);
        final CommunicationsSession commSession = new HttpCommunicationsSession();
        final String nodeApiUrl = resolveNodeApiUrl(peerStatus.getPeerDescription());
        final StringBuilder clusterUrls = new StringBuilder();
        config.getUrls().forEach(url -> {
            if (clusterUrls.length() > 0) {
                clusterUrls.append(",");
                clusterUrls.append(url);
            }
        });
        final Peer peer = new Peer(peerStatus.getPeerDescription(), commSession, nodeApiUrl, clusterUrls.toString());
        final int penaltyMillis = (int) config.getPenalizationPeriod(TimeUnit.MILLISECONDS);
        String portId = config.getPortIdentifier();
        if (StringUtils.isEmpty(portId)) {
            portId = siteInfoProvider.getPortIdentifier(config.getPortName(), direction);
            if (StringUtils.isEmpty(portId)) {
                peer.close();
                throw new IOException("Failed to determine the identifier of port " + config.getPortName());
            }
        }
        final SiteToSiteRestApiClient apiClient = new SiteToSiteRestApiClient(config.getSslContext(), config.getHttpProxy(), config.getEventReporter());
        apiClient.setBaseUrl(peer.getUrl());
        apiClient.setConnectTimeoutMillis(timeoutMillis);
        apiClient.setReadTimeoutMillis(timeoutMillis);
        apiClient.setCacheExpirationMillis(config.getCacheExpiration(TimeUnit.MILLISECONDS));
        apiClient.setLocalAddress(config.getLocalAddress());
        apiClient.setCompress(config.isUseCompression());
        apiClient.setRequestExpirationMillis(config.getIdleConnectionExpiration(TimeUnit.MILLISECONDS));
        apiClient.setBatchCount(config.getPreferredBatchCount());
        apiClient.setBatchSize(config.getPreferredBatchSize());
        apiClient.setBatchDurationMillis(config.getPreferredBatchDuration(TimeUnit.MILLISECONDS));
        final String transactionUrl;
        try {
            transactionUrl = apiClient.initiateTransaction(direction, portId);
            commSession.setUserDn(apiClient.getTrustedPeerDn());
        } catch (final Exception e) {
            apiClient.close();
            logger.warn("Penalizing a peer {} due to {}", peer, e.toString());
            peerSelector.penalize(peer, penaltyMillis);
            // Following exceptions will be thrown even if we tried other peers, so throw it.
            if (e instanceof UnknownPortException || e instanceof PortNotRunningException || e instanceof HandshakeException) {
                throw e;
            }
            logger.debug("Continue trying other peers...");
            continue;
        }
        // We found a valid peer to communicate with.
        final Integer transactionProtocolVersion = apiClient.getTransactionProtocolVersion();
        final HttpClientTransaction transaction = new HttpClientTransaction(transactionProtocolVersion, peer, direction, config.isUseCompression(), portId, penaltyMillis, config.getEventReporter()) {

            @Override
            protected void close() throws IOException {
                try {
                    super.close();
                } finally {
                    activeTransactions.remove(this);
                }
            }
        };
        try {
            transaction.initialize(apiClient, transactionUrl);
        } catch (final Exception e) {
            transaction.error();
            throw e;
        }
        activeTransactions.add(transaction);
        return transaction;
    }
    logger.info("Couldn't find a valid peer to communicate with.");
    return null;
}
Also used : HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) Peer(org.apache.nifi.remote.Peer) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) IOException(java.io.IOException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) IOException(java.io.IOException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) PeerStatus(org.apache.nifi.remote.PeerStatus) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) HttpClientTransaction(org.apache.nifi.remote.protocol.http.HttpClientTransaction)

Example 3 with SiteToSiteRestApiClient

use of org.apache.nifi.remote.util.SiteToSiteRestApiClient in project nifi by apache.

the class TestSiteInfoProvider method testConnectException.

@Test
public void testConnectException() throws Exception {
    final Set<String> expectedClusterUrl = new LinkedHashSet<>(Arrays.asList(new String[] { "http://node1:8443, http://node2:8443" }));
    final SiteInfoProvider siteInfoProvider = spy(new SiteInfoProvider());
    siteInfoProvider.setClusterUrls(expectedClusterUrl);
    final ControllerDTO controllerDTO = new ControllerDTO();
    controllerDTO.setInputPorts(Collections.emptySet());
    controllerDTO.setOutputPorts(Collections.emptySet());
    controllerDTO.setRemoteSiteListeningPort(8081);
    controllerDTO.setRemoteSiteHttpListeningPort(8080);
    controllerDTO.setSiteToSiteSecure(false);
    // SiteInfoProvider uses SiteToSIteRestApiClient to get ControllerDTO.
    doAnswer(invocation -> {
        final SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
        when(apiClient.getController(eq(expectedClusterUrl))).thenThrow(new IOException("Connection refused."));
        return apiClient;
    }).when(siteInfoProvider).createSiteToSiteRestApiClient(any(), any());
    try {
        siteInfoProvider.getSiteToSitePort();
        fail();
    } catch (IOException e) {
    }
    try {
        siteInfoProvider.getActiveClusterUrl();
        fail();
    } catch (IOException e) {
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) ControllerDTO(org.apache.nifi.web.api.dto.ControllerDTO) IOException(java.io.IOException) Test(org.junit.Test)

Example 4 with SiteToSiteRestApiClient

use of org.apache.nifi.remote.util.SiteToSiteRestApiClient in project nifi by apache.

the class TestHttpClientTransaction method testSendTwoFlowFiles.

@Test
public void testSendTwoFlowFiles() throws IOException {
    SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
    final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
    doNothing().when(apiClient).openConnectionForSend(eq("portId"), any(Peer.class));
    // Emulate that server returns correct checksum.
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            HttpCommunicationsSession commSession = (HttpCommunicationsSession) invocation.getArguments()[0];
            commSession.setChecksum("3359812065");
            return null;
        }
    }).when(apiClient).finishTransferFlowFiles(any(CommunicationsSession.class));
    TransactionResultEntity resultEntity = new TransactionResultEntity();
    resultEntity.setResponseCode(ResponseCode.TRANSACTION_FINISHED.getCode());
    doReturn(resultEntity).when(apiClient).commitTransferFlowFiles(eq(transactionUrl), eq(CONFIRM_TRANSACTION));
    ByteArrayOutputStream serverResponseBos = new ByteArrayOutputStream();
    ByteArrayInputStream serverResponse = new ByteArrayInputStream(serverResponseBos.toByteArray());
    ByteArrayOutputStream clientRequest = new ByteArrayOutputStream();
    HttpClientTransaction transaction = getClientTransaction(serverResponse, clientRequest, apiClient, TransferDirection.SEND, transactionUrl);
    execSendTwoFlowFiles(transaction);
    InputStream sentByClient = new ByteArrayInputStream(clientRequest.toByteArray());
    DataPacket packetByClient = codec.decode(sentByClient);
    assertEquals("contents on client 1", readContents(packetByClient));
    packetByClient = codec.decode(sentByClient);
    assertEquals("contents on client 2", readContents(packetByClient));
    assertEquals(-1, sentByClient.read());
    verify(apiClient).commitTransferFlowFiles(transactionUrl, CONFIRM_TRANSACTION);
}
Also used : TransactionResultEntity(org.apache.nifi.web.api.entity.TransactionResultEntity) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) ByteArrayInputStream(org.apache.nifi.stream.io.ByteArrayInputStream) InputStream(java.io.InputStream) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) Peer(org.apache.nifi.remote.Peer) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) ByteArrayOutputStream(org.apache.nifi.stream.io.ByteArrayOutputStream) DataPacket(org.apache.nifi.remote.protocol.DataPacket) SiteToSiteTestUtils.createDataPacket(org.apache.nifi.remote.protocol.SiteToSiteTestUtils.createDataPacket) Answer(org.mockito.stubbing.Answer) Mockito.doAnswer(org.mockito.Mockito.doAnswer) ByteArrayInputStream(org.apache.nifi.stream.io.ByteArrayInputStream) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Example 5 with SiteToSiteRestApiClient

use of org.apache.nifi.remote.util.SiteToSiteRestApiClient in project nifi by apache.

the class TestHttpClientTransaction method testSendWithInvalidChecksum.

@Test
public void testSendWithInvalidChecksum() throws IOException {
    SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
    final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
    doNothing().when(apiClient).openConnectionForSend(eq(transactionUrl), any(Peer.class));
    // Emulate that server returns incorrect checksum.
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            HttpCommunicationsSession commSession = (HttpCommunicationsSession) invocation.getArguments()[0];
            commSession.setChecksum("Different checksum");
            return null;
        }
    }).when(apiClient).finishTransferFlowFiles(any(CommunicationsSession.class));
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            TransactionResultEntity serverResult = new TransactionResultEntity();
            serverResult.setResponseCode(ResponseCode.CANCEL_TRANSACTION.getCode());
            return serverResult;
        }
    }).when(apiClient).commitTransferFlowFiles(eq(transactionUrl), eq(ResponseCode.BAD_CHECKSUM));
    ByteArrayOutputStream serverResponseBos = new ByteArrayOutputStream();
    ByteArrayInputStream serverResponse = new ByteArrayInputStream(serverResponseBos.toByteArray());
    ByteArrayOutputStream clientRequest = new ByteArrayOutputStream();
    HttpClientTransaction transaction = getClientTransaction(serverResponse, clientRequest, apiClient, TransferDirection.SEND, transactionUrl);
    execSendWithInvalidChecksum(transaction);
    InputStream sentByClient = new ByteArrayInputStream(clientRequest.toByteArray());
    DataPacket packetByClient = codec.decode(sentByClient);
    assertEquals("contents on client 1", readContents(packetByClient));
    packetByClient = codec.decode(sentByClient);
    assertEquals("contents on client 2", readContents(packetByClient));
    assertEquals(-1, sentByClient.read());
    verify(apiClient).commitTransferFlowFiles(transactionUrl, ResponseCode.BAD_CHECKSUM);
}
Also used : TransactionResultEntity(org.apache.nifi.web.api.entity.TransactionResultEntity) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) ByteArrayInputStream(org.apache.nifi.stream.io.ByteArrayInputStream) InputStream(java.io.InputStream) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) Peer(org.apache.nifi.remote.Peer) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) ByteArrayOutputStream(org.apache.nifi.stream.io.ByteArrayOutputStream) DataPacket(org.apache.nifi.remote.protocol.DataPacket) SiteToSiteTestUtils.createDataPacket(org.apache.nifi.remote.protocol.SiteToSiteTestUtils.createDataPacket) Answer(org.mockito.stubbing.Answer) Mockito.doAnswer(org.mockito.Mockito.doAnswer) ByteArrayInputStream(org.apache.nifi.stream.io.ByteArrayInputStream) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Aggregations

SiteToSiteRestApiClient (org.apache.nifi.remote.util.SiteToSiteRestApiClient)18 Test (org.junit.Test)12 Peer (org.apache.nifi.remote.Peer)11 ByteArrayInputStream (org.apache.nifi.stream.io.ByteArrayInputStream)9 ByteArrayOutputStream (org.apache.nifi.stream.io.ByteArrayOutputStream)9 TransactionResultEntity (org.apache.nifi.web.api.entity.TransactionResultEntity)7 HttpCommunicationsSession (org.apache.nifi.remote.io.http.HttpCommunicationsSession)6 CommunicationsSession (org.apache.nifi.remote.protocol.CommunicationsSession)6 IOException (java.io.IOException)4 InputStream (java.io.InputStream)4 DataPacket (org.apache.nifi.remote.protocol.DataPacket)4 SiteToSiteTestUtils.createDataPacket (org.apache.nifi.remote.protocol.SiteToSiteTestUtils.createDataPacket)4 ControllerDTO (org.apache.nifi.web.api.dto.ControllerDTO)4 Mockito.doAnswer (org.mockito.Mockito.doAnswer)4 InvocationOnMock (org.mockito.invocation.InvocationOnMock)4 Answer (org.mockito.stubbing.Answer)4 LinkedHashSet (java.util.LinkedHashSet)3 URI (java.net.URI)2 HashSet (java.util.HashSet)2 PeerStatus (org.apache.nifi.remote.PeerStatus)2