Search in sources :

Example 1 with QueryResult

use of org.apache.nifi.provenance.search.QueryResult in project nifi by apache.

the class ControllerFacade method getProvenanceQuery.

/**
 * Retrieves the results of a provenance query.
 *
 * @param provenanceId id
 * @return the results of a provenance query
 */
public ProvenanceDTO getProvenanceQuery(String provenanceId, Boolean summarize, Boolean incrementalResults) {
    try {
        // get the query to the provenance repository
        final ProvenanceRepository provenanceRepository = flowController.getProvenanceRepository();
        final QuerySubmission querySubmission = provenanceRepository.retrieveQuerySubmission(provenanceId, NiFiUserUtils.getNiFiUser());
        // ensure the query results could be found
        if (querySubmission == null) {
            throw new ResourceNotFoundException("Cannot find the results for the specified provenance requests. Results may have been purged.");
        }
        // get the original query and the results
        final Query query = querySubmission.getQuery();
        final QueryResult queryResult = querySubmission.getResult();
        // build the response
        final ProvenanceDTO provenanceDto = new ProvenanceDTO();
        final ProvenanceRequestDTO requestDto = new ProvenanceRequestDTO();
        final ProvenanceResultsDTO resultsDto = new ProvenanceResultsDTO();
        // include the original request and results
        provenanceDto.setRequest(requestDto);
        provenanceDto.setResults(resultsDto);
        // convert the original request
        requestDto.setStartDate(query.getStartDate());
        requestDto.setEndDate(query.getEndDate());
        requestDto.setMinimumFileSize(query.getMinFileSize());
        requestDto.setMaximumFileSize(query.getMaxFileSize());
        requestDto.setMaxResults(query.getMaxResults());
        if (query.getSearchTerms() != null) {
            final Map<String, String> searchTerms = new HashMap<>();
            for (final SearchTerm searchTerm : query.getSearchTerms()) {
                searchTerms.put(searchTerm.getSearchableField().getFriendlyName(), searchTerm.getValue());
            }
            requestDto.setSearchTerms(searchTerms);
        }
        // convert the provenance
        provenanceDto.setId(query.getIdentifier());
        provenanceDto.setSubmissionTime(querySubmission.getSubmissionTime());
        provenanceDto.setExpiration(queryResult.getExpiration());
        provenanceDto.setFinished(queryResult.isFinished());
        provenanceDto.setPercentCompleted(queryResult.getPercentComplete());
        // convert each event
        final boolean includeResults = incrementalResults == null || Boolean.TRUE.equals(incrementalResults);
        if (includeResults || queryResult.isFinished()) {
            final List<ProvenanceEventDTO> events = new ArrayList<>();
            for (final ProvenanceEventRecord record : queryResult.getMatchingEvents()) {
                events.add(createProvenanceEventDto(record, Boolean.TRUE.equals(summarize)));
            }
            resultsDto.setProvenanceEvents(events);
        }
        if (requestDto.getMaxResults() != null && queryResult.getTotalHitCount() >= requestDto.getMaxResults()) {
            resultsDto.setTotalCount(requestDto.getMaxResults().longValue());
            resultsDto.setTotal(FormatUtils.formatCount(requestDto.getMaxResults().longValue()) + "+");
        } else {
            resultsDto.setTotalCount(queryResult.getTotalHitCount());
            resultsDto.setTotal(FormatUtils.formatCount(queryResult.getTotalHitCount()));
        }
        // include any errors
        if (queryResult.getError() != null) {
            final Set<String> errors = new HashSet<>();
            errors.add(queryResult.getError());
            resultsDto.setErrors(errors);
        }
        // set the generated timestamp
        final Date now = new Date();
        resultsDto.setGenerated(now);
        resultsDto.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
        // get the oldest available event time
        final List<ProvenanceEventRecord> firstEvent = provenanceRepository.getEvents(0, 1);
        if (!firstEvent.isEmpty()) {
            resultsDto.setOldestEvent(new Date(firstEvent.get(0).getEventTime()));
        }
        provenanceDto.setResults(resultsDto);
        return provenanceDto;
    } catch (final IOException ioe) {
        throw new NiFiCoreException("An error occurred while searching the provenance events.", ioe);
    }
}
Also used : NiFiCoreException(org.apache.nifi.web.NiFiCoreException) QuerySubmission(org.apache.nifi.provenance.search.QuerySubmission) Query(org.apache.nifi.provenance.search.Query) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProvenanceResultsDTO(org.apache.nifi.web.api.dto.provenance.ProvenanceResultsDTO) IOException(java.io.IOException) SearchTerm(org.apache.nifi.provenance.search.SearchTerm) ProvenanceRequestDTO(org.apache.nifi.web.api.dto.provenance.ProvenanceRequestDTO) Date(java.util.Date) QueryResult(org.apache.nifi.provenance.search.QueryResult) ProvenanceEventDTO(org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO) ProvenanceEventRecord(org.apache.nifi.provenance.ProvenanceEventRecord) ProvenanceRepository(org.apache.nifi.provenance.ProvenanceRepository) ProvenanceDTO(org.apache.nifi.web.api.dto.provenance.ProvenanceDTO) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) HashSet(java.util.HashSet)

Example 2 with QueryResult

use of org.apache.nifi.provenance.search.QueryResult in project nifi by apache.

the class TestPersistentProvenanceRepository method testModifyIndexWhileSearching.

@Test(timeout = 10000)
public void testModifyIndexWhileSearching() throws IOException, InterruptedException, ParseException {
    assumeFalse(isWindowsEnvironment());
    final RepositoryConfiguration config = createConfiguration();
    config.setMaxRecordLife(30, TimeUnit.SECONDS);
    config.setMaxStorageCapacity(1024L * 1024L * 10);
    config.setMaxEventFileLife(500, TimeUnit.MILLISECONDS);
    config.setMaxEventFileCapacity(1024L * 1024L * 10);
    config.setSearchableFields(new ArrayList<>(SearchableFields.getStandardFields()));
    final CountDownLatch obtainIndexSearcherLatch = new CountDownLatch(2);
    repo = new PersistentProvenanceRepository(config, DEFAULT_ROLLOVER_MILLIS) {

        private CachingIndexManager wrappedManager = null;

        // Create an IndexManager that adds a delay before returning the Index Searcher.
        @Override
        protected synchronized CachingIndexManager getIndexManager() {
            if (wrappedManager == null) {
                final IndexManager mgr = super.getIndexManager();
                final Logger logger = LoggerFactory.getLogger("IndexManager");
                wrappedManager = new CachingIndexManager() {

                    final AtomicInteger indexSearcherCount = new AtomicInteger(0);

                    @Override
                    public EventIndexSearcher borrowIndexSearcher(File indexDir) throws IOException {
                        final EventIndexSearcher searcher = mgr.borrowIndexSearcher(indexDir);
                        final int idx = indexSearcherCount.incrementAndGet();
                        obtainIndexSearcherLatch.countDown();
                        // second thread is still holding the searcher
                        try {
                            if (idx == 1) {
                                Thread.sleep(3000L);
                            } else {
                                Thread.sleep(5000L);
                            }
                        } catch (InterruptedException e) {
                            throw new IOException("Interrupted", e);
                        }
                        logger.info("Releasing index searcher");
                        return searcher;
                    }

                    @Override
                    public EventIndexWriter borrowIndexWriter(File indexingDirectory) throws IOException {
                        return mgr.borrowIndexWriter(indexingDirectory);
                    }

                    @Override
                    public void close() throws IOException {
                        mgr.close();
                    }

                    @Override
                    public boolean removeIndex(File indexDirectory) {
                        mgr.removeIndex(indexDirectory);
                        return true;
                    }

                    @Override
                    public void returnIndexSearcher(EventIndexSearcher searcher) {
                        mgr.returnIndexSearcher(searcher);
                    }

                    @Override
                    public void returnIndexWriter(EventIndexWriter writer) {
                        mgr.returnIndexWriter(writer);
                    }
                };
            }
            return wrappedManager;
        }
    };
    repo.initialize(getEventReporter(), null, null, IdentifierLookup.EMPTY);
    final String uuid = "10000000-0000-0000-0000-000000000000";
    final Map<String, String> attributes = new HashMap<>();
    attributes.put("abc", "xyz");
    attributes.put("xyz", "abc");
    attributes.put("filename", "file-" + uuid);
    final ProvenanceEventBuilder builder = new StandardProvenanceEventRecord.Builder();
    builder.setEventTime(System.currentTimeMillis());
    builder.setEventType(ProvenanceEventType.RECEIVE);
    builder.setTransitUri("nifi://unit-test");
    attributes.put("uuid", uuid);
    builder.fromFlowFile(createFlowFile(3L, 3000L, attributes));
    builder.setComponentId("1234");
    builder.setComponentType("dummy processor");
    for (int i = 0; i < 10; i++) {
        builder.fromFlowFile(createFlowFile(i, 3000L, attributes));
        attributes.put("uuid", "00000000-0000-0000-0000-00000000000" + i);
        repo.registerEvent(builder.build());
    }
    repo.waitForRollover();
    // Perform a query. This will ensure that an IndexSearcher is created and cached.
    final Query query = new Query(UUID.randomUUID().toString());
    query.addSearchTerm(SearchTerms.newSearchTerm(SearchableFields.Filename, "file-*"));
    query.addSearchTerm(SearchTerms.newSearchTerm(SearchableFields.ComponentID, "12?4"));
    query.addSearchTerm(SearchTerms.newSearchTerm(SearchableFields.TransitURI, "nifi://*"));
    query.setMaxResults(100);
    // Run a query in a background thread. When this thread goes to obtain the IndexSearcher, it will have a 5 second delay.
    // That delay will occur as the main thread is updating the index. This should result in the search creating a new Index Reader
    // that can properly query the index.
    final int numThreads = 2;
    final CountDownLatch performSearchLatch = new CountDownLatch(numThreads);
    final Runnable searchRunnable = new Runnable() {

        @Override
        public void run() {
            QueryResult result;
            try {
                result = repo.queryEvents(query, createUser());
            } catch (IOException e) {
                e.printStackTrace();
                Assert.fail(e.toString());
                return;
            }
            System.out.println("Finished search: " + result);
            performSearchLatch.countDown();
        }
    };
    // Kick off the searcher threads
    for (int i = 0; i < numThreads; i++) {
        final Thread searchThread = new Thread(searchRunnable);
        searchThread.start();
    }
    // Wait until we've obtained the Index Searchers before modifying the index.
    obtainIndexSearcherLatch.await();
    // add more events to the repo
    for (int i = 0; i < 10; i++) {
        builder.fromFlowFile(createFlowFile(i, 3000L, attributes));
        attributes.put("uuid", "00000000-0000-0000-0000-00000000000" + i);
        repo.registerEvent(builder.build());
    }
    // Force a rollover to occur. This will modify the index.
    repo.rolloverWithLock(true);
    // Wait for the repository to roll over.
    repo.waitForRollover();
    // Wait for the searches to complete.
    performSearchLatch.await();
}
Also used : Query(org.apache.nifi.provenance.search.Query) CachingIndexManager(org.apache.nifi.provenance.lucene.CachingIndexManager) HashMap(java.util.HashMap) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) Logger(org.slf4j.Logger) IndexManager(org.apache.nifi.provenance.lucene.IndexManager) CachingIndexManager(org.apache.nifi.provenance.lucene.CachingIndexManager) QueryResult(org.apache.nifi.provenance.search.QueryResult) EventIndexSearcher(org.apache.nifi.provenance.index.EventIndexSearcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EventIndexWriter(org.apache.nifi.provenance.index.EventIndexWriter) TestUtil.createFlowFile(org.apache.nifi.provenance.TestUtil.createFlowFile) FlowFile(org.apache.nifi.flowfile.FlowFile) File(java.io.File) Test(org.junit.Test)

Example 3 with QueryResult

use of org.apache.nifi.provenance.search.QueryResult in project nifi by apache.

the class TestPersistentProvenanceRepository method testIndexAndCompressOnRolloverAndSubsequentEmptySearch.

@Test
public void testIndexAndCompressOnRolloverAndSubsequentEmptySearch() throws IOException, InterruptedException, ParseException {
    assumeFalse(isWindowsEnvironment());
    final RepositoryConfiguration config = createConfiguration();
    config.setMaxRecordLife(30, TimeUnit.SECONDS);
    config.setMaxStorageCapacity(1024L * 1024L);
    config.setMaxEventFileLife(500, TimeUnit.MILLISECONDS);
    config.setMaxEventFileCapacity(1024L * 1024L);
    config.setSearchableFields(new ArrayList<>(SearchableFields.getStandardFields()));
    repo = new PersistentProvenanceRepository(config, DEFAULT_ROLLOVER_MILLIS);
    repo.initialize(getEventReporter(), null, null, IdentifierLookup.EMPTY);
    final String uuid = "00000000-0000-0000-0000-000000000000";
    final Map<String, String> attributes = new HashMap<>();
    attributes.put("abc", "xyz");
    attributes.put("xyz", "abc");
    attributes.put("filename", "file-" + uuid);
    final ProvenanceEventBuilder builder = new StandardProvenanceEventRecord.Builder();
    builder.setEventTime(System.currentTimeMillis());
    builder.setEventType(ProvenanceEventType.RECEIVE);
    builder.setTransitUri("nifi://unit-test");
    attributes.put("uuid", uuid);
    builder.fromFlowFile(createFlowFile(3L, 3000L, attributes));
    builder.setComponentId("1234");
    builder.setComponentType("dummy processor");
    for (int i = 0; i < 10; i++) {
        builder.fromFlowFile(createFlowFile(i, 3000L, attributes));
        repo.registerEvent(builder.build());
    }
    // Give time for rollover to happen
    repo.waitForRollover();
    final Query query = new Query(UUID.randomUUID().toString());
    query.setMaxResults(100);
    final QueryResult result = repo.queryEvents(query, createUser());
    assertEquals(10, result.getMatchingEvents().size());
    for (final ProvenanceEventRecord match : result.getMatchingEvents()) {
        System.out.println(match);
    }
    Thread.sleep(2000L);
    config.setMaxStorageCapacity(100L);
    config.setMaxRecordLife(500, TimeUnit.MILLISECONDS);
    repo.purgeOldEvents();
    Thread.sleep(1000L);
    final QueryResult newRecordSet = repo.queryEvents(query, createUser());
    assertTrue(newRecordSet.getMatchingEvents().isEmpty());
}
Also used : QueryResult(org.apache.nifi.provenance.search.QueryResult) Query(org.apache.nifi.provenance.search.Query) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 4 with QueryResult

use of org.apache.nifi.provenance.search.QueryResult in project nifi by apache.

the class TestPersistentProvenanceRepository method testWithWithEventFileMissingRecord.

/**
 * Here the event file is simply corrupted by virtue of not having any event
 * records while having correct headers
 */
@Test
public void testWithWithEventFileMissingRecord() throws Exception {
    assumeFalse(isWindowsEnvironment());
    File eventFile = this.prepCorruptedEventFileTests();
    final Query query = new Query(UUID.randomUUID().toString());
    query.addSearchTerm(SearchTerms.newSearchTerm(SearchableFields.ComponentID, "foo-*"));
    query.setMaxResults(100);
    DataOutputStream in = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(eventFile)));
    in.writeUTF("BlahBlah");
    in.writeInt(4);
    in.close();
    assertTrue(eventFile.exists());
    final QueryResult result = repo.queryEvents(query, createUser());
    assertEquals(10, result.getMatchingEvents().size());
}
Also used : QueryResult(org.apache.nifi.provenance.search.QueryResult) Query(org.apache.nifi.provenance.search.Query) GZIPOutputStream(java.util.zip.GZIPOutputStream) DataOutputStream(java.io.DataOutputStream) FileOutputStream(java.io.FileOutputStream) TestUtil.createFlowFile(org.apache.nifi.provenance.TestUtil.createFlowFile) FlowFile(org.apache.nifi.flowfile.FlowFile) File(java.io.File) Test(org.junit.Test)

Example 5 with QueryResult

use of org.apache.nifi.provenance.search.QueryResult in project nifi by apache.

the class TestPersistentProvenanceRepository method testWithWithEventFileCorrupted.

/**
 * Here the event file is simply corrupted by virtue of being empty (0
 * bytes)
 */
@Test
public void testWithWithEventFileCorrupted() throws Exception {
    assumeFalse(isWindowsEnvironment());
    File eventFile = this.prepCorruptedEventFileTests();
    final Query query = new Query(UUID.randomUUID().toString());
    query.addSearchTerm(SearchTerms.newSearchTerm(SearchableFields.ComponentID, "foo-*"));
    query.setMaxResults(100);
    DataOutputStream in = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(eventFile)));
    in.close();
    final QueryResult result = repo.queryEvents(query, createUser());
    assertEquals(10, result.getMatchingEvents().size());
}
Also used : QueryResult(org.apache.nifi.provenance.search.QueryResult) Query(org.apache.nifi.provenance.search.Query) GZIPOutputStream(java.util.zip.GZIPOutputStream) DataOutputStream(java.io.DataOutputStream) FileOutputStream(java.io.FileOutputStream) TestUtil.createFlowFile(org.apache.nifi.provenance.TestUtil.createFlowFile) FlowFile(org.apache.nifi.flowfile.FlowFile) File(java.io.File) Test(org.junit.Test)

Aggregations

QueryResult (org.apache.nifi.provenance.search.QueryResult)16 Query (org.apache.nifi.provenance.search.Query)13 Test (org.junit.Test)12 HashMap (java.util.HashMap)9 QuerySubmission (org.apache.nifi.provenance.search.QuerySubmission)8 IOException (java.io.IOException)6 File (java.io.File)4 FlowFile (org.apache.nifi.flowfile.FlowFile)4 TestUtil.createFlowFile (org.apache.nifi.provenance.TestUtil.createFlowFile)4 IndexManager (org.apache.nifi.provenance.lucene.IndexManager)4 DataOutputStream (java.io.DataOutputStream)3 FileOutputStream (java.io.FileOutputStream)3 ArrayList (java.util.ArrayList)3 GZIPOutputStream (java.util.zip.GZIPOutputStream)3 HashSet (java.util.HashSet)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 NiFiUser (org.apache.nifi.authorization.user.NiFiUser)2 ProvenanceEventRecord (org.apache.nifi.provenance.ProvenanceEventRecord)2