METRON-1700 Create REST endpoint to get job configuration (merrimanr) closes apache/metron#1135
Project: http://git-wip-us.apache.org/repos/asf/metron/repo Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/2b6959b4 Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/2b6959b4 Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/2b6959b4 Branch: refs/heads/master Commit: 2b6959b46db79256d12b8522385212559cabada2 Parents: d5eb56a Author: merrimanr <merrim...@gmail.com> Authored: Thu Aug 2 12:17:37 2018 -0500 Committer: rmerriman <merrim...@gmail.com> Committed: Thu Aug 2 12:17:37 2018 -0500 ---------------------------------------------------------------------- metron-interface/metron-rest/README.md | 10 ++ .../metron/rest/controller/PcapController.java | 16 +++ .../apache/metron/rest/service/PcapService.java | 71 ++++++++++++- .../rest/service/impl/PcapServiceImpl.java | 54 +++++++++- .../PcapControllerIntegrationTest.java | 50 ++++++++++ .../apache/metron/rest/mock/MockPcapJob.java | 4 +- .../rest/service/impl/PcapServiceImplTest.java | 100 +++++++++++++++++++ .../java/org/apache/metron/job/Statusable.java | 2 + .../java/org/apache/metron/pcap/mr/PcapJob.java | 5 + 9 files changed, 306 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/README.md ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/README.md b/metron-interface/metron-rest/README.md index 68ec559..489cd9f 100644 --- a/metron-interface/metron-rest/README.md +++ b/metron-interface/metron-rest/README.md @@ -259,6 +259,8 @@ Request and Response objects are JSON formatted. The JSON schemas are available | [ `GET /api/v1/pcap/{jobId}`](#get-apiv1pcapjobid)| | [ `GET /api/v1/pcap/{jobId}/pdml`](#get-apiv1pcapjobidpdml)| | [ `GET /api/v1/pcap/{jobId}/raw`](#get-apiv1pcapjobidraw)| +| [ `DELETE /api/v1/pcap/kill/{jobId}`](#delete-apiv1pcapkilljobid)| +| [ `GET /api/v1/pcap/{jobId}/config`](#get-apiv1pcapjobidconfig)| | [ `GET /api/v1/search/search`](#get-apiv1searchsearch)| | [ `POST /api/v1/search/search`](#post-apiv1searchsearch)| | [ `POST /api/v1/search/group`](#post-apiv1searchgroup)| @@ -556,6 +558,14 @@ Request and Response objects are JSON formatted. The JSON schemas are available * jobId - Job ID of submitted job * Returns: * 200 - Kills passed job. + +### `GET /api/v1/pcap/{jobId}/config` + * Description: Gets job configuration for Pcap query job. + * Input: + * jobId - Job ID of submitted job + * Returns: + * 200 - Returns a map of job properties for the Job ID. + * 404 - Job is missing. ### `POST /api/v1/search/search` * Description: Searches the indexing store. GUIDs must be quoted to ensure correct results. http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/PcapController.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/PcapController.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/PcapController.java index 13a623a..97713d8 100644 --- a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/PcapController.java +++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/PcapController.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.Map; @RestController @RequestMapping("/api/v1/pcap") @@ -161,4 +162,19 @@ public class PcapController { } } + @ApiOperation(value = "Gets job configuration for Pcap query job.") + @ApiResponses(value = { + @ApiResponse(message = "Returns a map of job properties for the Job ID.", code = 200), + @ApiResponse(message = "Job is missing.", code = 404) + }) + @RequestMapping(value = "/{jobId}/config", method = RequestMethod.GET) + ResponseEntity<Map<String, Object>> getConfiguration(@ApiParam(name="jobId", value="Job ID of submitted job", required=true)@PathVariable String jobId) throws RestException { + Map<String, Object> configuration = pcapQueryService.getConfiguration(SecurityUtils.getCurrentUser(), jobId); + if (configuration != null) { + return new ResponseEntity<>(configuration, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + } http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/PcapService.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/PcapService.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/PcapService.java index 00efab9..5ec937f 100644 --- a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/PcapService.java +++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/PcapService.java @@ -26,22 +26,91 @@ import org.apache.metron.rest.model.pcap.Pdml; import java.io.InputStream; import java.util.List; +import java.util.Map; public interface PcapService { + /** + * Submits a pcap query. Jobs that do not match any pcap data will return a status without a job id and a + * description of why data did not match. + * + * @param username User that is submitting the job + * @param pcapRequest Either a fixed or query filter pcap request + * @return Status of the submitted job + * @throws RestException + */ PcapStatus submit(String username, PcapRequest pcapRequest) throws RestException; + /** + * Returns the status of a job given a job id and user who submitted it. + * + * @param username User that submitted the job + * @param jobId Job id of a submitted job + * @return Status of the submitted job or null if job does not exist + * @throws RestException + */ PcapStatus getJobStatus(String username, String jobId) throws RestException; + /** + * Returns a list of statuses for jobs a user has submitted that match the given job state. + * + * @param username User that submitted the job + * @param state Job state + * @return List of job statuses of an empty list of no jobs match + * @throws RestException + */ List<PcapStatus> getJobStatus(String username, JobStatus.State state) throws RestException; + /** + * Kills a running job. + * + * @param username User that submitted the job + * @param jobId Job id of a submitted job + * @return Status of the killed job + * @throws RestException + */ PcapStatus killJob(String username, String jobId) throws RestException; + /** + * Gets an HDFS path to results of a pcap query given a user, job id and page number. + * + * @param username User that submitted the job + * @param jobId Job id + * @param page Page number + * @return HDFS path to results + * @throws RestException + */ Path getPath(String username, String jobId, Integer page) throws RestException; + /** + * Gets pcap query results in <a href="https://wiki.wireshark.org/PDML">PDML</a> format for a given user, job id and page number. + * + * @param username User that submitted the job + * @param jobId Job id + * @param page Page number + * @return Results in PDML format + * @throws RestException + */ Pdml getPdml(String username, String jobId, Integer page) throws RestException; + /** + * Returns an input stream of raw binary pcap results for a given user, job id and page number. + * + * @param username User that submitted the job + * @param jobId Job id + * @param page Page number + * @return Input stream of raw pcap results + * @throws RestException + */ InputStream getRawPcap(String username, String jobId, Integer page) throws RestException; - + /** + * Gets the configuration of a submitted pcap query. Internal properties such as file system, hadoop config, etc are not included. + * + * @param username User that submitted the job + * @param jobId Job id + * @return Configuration of a submitted pcap query + * @throws RestException + */ + Map<String, Object> getConfiguration(String username, String jobId) throws RestException; } http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapServiceImpl.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapServiceImpl.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapServiceImpl.java index ff80c8f..f3af0dd 100644 --- a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapServiceImpl.java +++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapServiceImpl.java @@ -28,26 +28,40 @@ import org.apache.metron.job.Pageable; import org.apache.metron.job.Statusable; import org.apache.metron.job.manager.JobManager; import org.apache.metron.pcap.config.PcapOptions; +import org.apache.metron.pcap.filter.PcapFilterConfigurator; +import org.apache.metron.pcap.filter.fixed.FixedPcapFilter; +import org.apache.metron.pcap.filter.query.QueryPcapFilter; import org.apache.metron.rest.MetronRestConstants; import org.apache.metron.rest.RestException; import org.apache.metron.rest.config.PcapJobSupplier; +import org.apache.metron.rest.model.pcap.FixedPcapOptions; import org.apache.metron.rest.model.pcap.PcapRequest; import org.apache.metron.rest.model.pcap.PcapStatus; import org.apache.metron.rest.model.pcap.Pdml; +import org.apache.metron.rest.model.pcap.QueryPcapOptions; import org.apache.metron.rest.service.PcapService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.InputStream; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; @Service public class PcapServiceImpl implements PcapService { + private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private Environment environment; private Configuration configuration; private PcapJobSupplier pcapJobSupplier; @@ -93,7 +107,7 @@ public class PcapServiceImpl implements PcapService { pcapStatus = statusableToPcapStatus(statusable); } } catch (JobNotFoundException | InterruptedException e) { - // do nothing and return null pcapStatus + LOG.warn(String.format("Could not get job status. Job not found for user %s with job id %s", username, jobId)); } catch (JobException e) { throw new RestException(e); } @@ -139,7 +153,7 @@ public class PcapServiceImpl implements PcapService { try { jobManager.killJob(username, jobId); } catch (JobNotFoundException e) { - // do nothing and return null pcapStatus + LOG.warn(String.format("Could not kill job. Job not found for user %s with job id %s", username, jobId)); return null; } catch (JobException e) { throw new RestException(e); @@ -159,7 +173,7 @@ public class PcapServiceImpl implements PcapService { } } } catch (JobNotFoundException e) { - // do nothing and return null pcapStatus + LOG.warn(String.format("Could not get path for page %s. Job not found for user %s with job id %s", page, username, jobId)); } catch (JobException | InterruptedException e) { throw new RestException(e); } @@ -199,6 +213,40 @@ public class PcapServiceImpl implements PcapService { return inputStream; } + @Override + public Map<String, Object> getConfiguration(String username, String jobId) throws RestException { + Map<String, Object> configuration = new HashMap<>(); + try { + Statusable<Path> statusable = jobManager.getJob(username, jobId); + if (statusable != null) { + Map<String, Object> jobConfiguration = statusable.getConfiguration(); + configuration.put(PcapOptions.BASE_PATH.getKey(), PcapOptions.BASE_PATH.get(jobConfiguration, String.class)); + configuration.put(PcapOptions.FINAL_OUTPUT_PATH.getKey(), PcapOptions.FINAL_OUTPUT_PATH.get(jobConfiguration, String.class)); + configuration.put(PcapOptions.START_TIME_MS.getKey(), PcapOptions.START_TIME_MS.get(jobConfiguration, String.class)); + configuration.put(PcapOptions.END_TIME_MS.getKey(), PcapOptions.END_TIME_MS.get(jobConfiguration, String.class)); + configuration.put(PcapOptions.NUM_REDUCERS.getKey(), PcapOptions.NUM_REDUCERS.get(jobConfiguration, Integer.class)); + + boolean isFixedFilter = PcapOptions.FILTER_IMPL.get(jobConfiguration, PcapFilterConfigurator.class) instanceof FixedPcapFilter.Configurator; + if (isFixedFilter) { + configuration.put(FixedPcapOptions.IP_SRC_ADDR.getKey(), FixedPcapOptions.IP_SRC_ADDR.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.IP_DST_ADDR.getKey(), FixedPcapOptions.IP_DST_ADDR.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.IP_SRC_PORT.getKey(), FixedPcapOptions.IP_SRC_PORT.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.IP_DST_PORT.getKey(), FixedPcapOptions.IP_DST_PORT.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.PROTOCOL.getKey(), FixedPcapOptions.PROTOCOL.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.PACKET_FILTER.getKey(), FixedPcapOptions.PACKET_FILTER.get(jobConfiguration, String.class)); + configuration.put(FixedPcapOptions.INCLUDE_REVERSE.getKey(), FixedPcapOptions.INCLUDE_REVERSE.get(jobConfiguration, String.class)); + } else { + configuration.put(QueryPcapOptions.QUERY.getKey(), QueryPcapOptions.QUERY.get(jobConfiguration, String.class)); + } + } + } catch (JobNotFoundException e) { + LOG.warn(String.format("Could not get job configuration. Job not found for user %s with job id %s", username, jobId)); + } catch (JobException e) { + throw new RestException(e); + } + return configuration; + } + protected void setPcapOptions(String username, PcapRequest pcapRequest) throws IOException { PcapOptions.JOB_NAME.put(pcapRequest, "jobName"); PcapOptions.USERNAME.put(pcapRequest, username); http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/controller/PcapControllerIntegrationTest.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/controller/PcapControllerIntegrationTest.java b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/controller/PcapControllerIntegrationTest.java index 5d30e72..2d7c505 100644 --- a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/controller/PcapControllerIntegrationTest.java +++ b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/controller/PcapControllerIntegrationTest.java @@ -420,5 +420,55 @@ public class PcapControllerIntegrationTest { .andExpect(status().isNotFound()); } + @Test + public void testGetFixedFilterConfiguration() throws Exception { + MockPcapJob mockPcapJob = (MockPcapJob) wac.getBean("mockPcapJob"); + + mockPcapJob.setStatus(new JobStatus().withJobId("jobId").withState(JobStatus.State.RUNNING)); + + this.mockMvc.perform(post(pcapUrl + "/fixed").with(httpBasic(user, password)).with(csrf()).contentType(MediaType.parseMediaType("application/json;charset=UTF-8")).content(fixedJson)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))) + .andExpect(jsonPath("$.jobId").value("jobId")) + .andExpect(jsonPath("$.jobStatus").value("RUNNING")); + + this.mockMvc.perform(get(pcapUrl + "/jobId/config").with(httpBasic(user, password))) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))) + .andExpect(jsonPath("$.basePath").value("/base/path")) + .andExpect(jsonPath("$.finalOutputPath").value("/final/output/path")) + .andExpect(jsonPath("$.startTimeMs").value(10)) + .andExpect(jsonPath("$.endTimeMs").value(20)) + .andExpect(jsonPath("$.numReducers").value(2)) + .andExpect(jsonPath("$.ipSrcAddr").value("192.168.1.2")) + .andExpect(jsonPath("$.ipDstAddr").value("192.168.1.1")) + .andExpect(jsonPath("$.ipSrcPort").value("2000")) + .andExpect(jsonPath("$.ipDstPort").value("1000")) + .andExpect(jsonPath("$.protocol").value("TCP")) + .andExpect(jsonPath("$.packetFilter").value("filter")) + .andExpect(jsonPath("$.includeReverse").value("true")); + } + @Test + public void testGetQueryFilterConfiguration() throws Exception { + MockPcapJob mockPcapJob = (MockPcapJob) wac.getBean("mockPcapJob"); + + mockPcapJob.setStatus(new JobStatus().withJobId("jobId").withState(JobStatus.State.RUNNING)); + + this.mockMvc.perform(post(pcapUrl + "/query").with(httpBasic(user, password)).with(csrf()).contentType(MediaType.parseMediaType("application/json;charset=UTF-8")).content(queryJson)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))) + .andExpect(jsonPath("$.jobId").value("jobId")) + .andExpect(jsonPath("$.jobStatus").value("RUNNING")); + + this.mockMvc.perform(get(pcapUrl + "/jobId/config").with(httpBasic(user, password))) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))) + .andExpect(jsonPath("$.basePath").value("/base/path")) + .andExpect(jsonPath("$.finalOutputPath").value("/final/output/path")) + .andExpect(jsonPath("$.startTimeMs").value(10)) + .andExpect(jsonPath("$.endTimeMs").value(20)) + .andExpect(jsonPath("$.numReducers").value(2)) + .andExpect(jsonPath("$.query").value("query")); + } } http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapJob.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapJob.java b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapJob.java index 6a954e8..779589d 100644 --- a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapJob.java +++ b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapJob.java @@ -18,7 +18,6 @@ package org.apache.metron.rest.mock; import org.apache.hadoop.fs.Path; -import org.apache.metron.common.hadoop.SequenceFileIterable; import org.apache.metron.job.Finalizer; import org.apache.metron.job.JobException; import org.apache.metron.job.JobStatus; @@ -28,7 +27,7 @@ import org.apache.metron.pcap.config.PcapOptions; import org.apache.metron.pcap.filter.PcapFilterConfigurator; import org.apache.metron.pcap.mr.PcapJob; -import java.util.List; +import java.util.HashMap; import java.util.Map; import static org.mockito.Mockito.mock; @@ -54,6 +53,7 @@ public class MockPcapJob extends PcapJob<Path> { @Override public Statusable<Path> submit(Finalizer<Path> finalizer, Map<String, Object> configuration) throws JobException { + when(statusable.getConfiguration()).thenReturn(new HashMap<>(configuration)); this.basePath = PcapOptions.BASE_PATH.get(configuration, String.class); this.baseInterrimResultPath = PcapOptions.BASE_INTERIM_RESULT_PATH.get(configuration, String.class); this.finalOutputPath = PcapOptions.FINAL_OUTPUT_PATH.get(configuration, String.class); http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/service/impl/PcapServiceImplTest.java ---------------------------------------------------------------------- diff --git a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/service/impl/PcapServiceImplTest.java b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/service/impl/PcapServiceImplTest.java index f99ab93..2552df7 100644 --- a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/service/impl/PcapServiceImplTest.java +++ b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/service/impl/PcapServiceImplTest.java @@ -32,6 +32,7 @@ import org.apache.metron.job.Statusable; import org.apache.metron.job.manager.InMemoryJobManager; import org.apache.metron.job.manager.JobManager; import org.apache.metron.pcap.PcapHelper; +import org.apache.metron.pcap.config.PcapOptions; import org.apache.metron.pcap.filter.fixed.FixedPcapFilter; import org.apache.metron.pcap.filter.query.QueryPcapFilter; import org.apache.metron.rest.MetronRestConstants; @@ -39,7 +40,9 @@ import org.apache.metron.rest.RestException; import org.apache.metron.rest.config.PcapJobSupplier; import org.apache.metron.rest.mock.MockPcapJob; import org.apache.metron.rest.mock.MockPcapJobSupplier; +import org.apache.metron.rest.model.pcap.FixedPcapOptions; import org.apache.metron.rest.model.pcap.FixedPcapRequest; +import org.apache.metron.rest.model.pcap.QueryPcapOptions; import org.apache.metron.rest.model.pcap.QueryPcapRequest; import org.apache.metron.rest.model.pcap.PcapStatus; import org.apache.metron.rest.model.pcap.Pdml; @@ -639,4 +642,101 @@ public class PcapServiceImplTest { pcapService.getRawPcap("user", "jobId", 1); } + @Test + public void getConfigurationShouldProperlyReturnFixedFilterConfiguration() throws Exception { + FixedPcapRequest fixedPcapRequest = new FixedPcapRequest(); + fixedPcapRequest.setBasePath("basePath"); + fixedPcapRequest.setBaseInterimResultPath("baseOutputPath"); + fixedPcapRequest.setFinalOutputPath("finalOutputPath"); + fixedPcapRequest.setStartTimeMs(1L); + fixedPcapRequest.setEndTimeMs(2L); + fixedPcapRequest.setNumReducers(2); + fixedPcapRequest.setIpSrcAddr("ip_src_addr"); + fixedPcapRequest.setIpDstAddr("ip_dst_addr"); + fixedPcapRequest.setIpSrcPort(1000); + fixedPcapRequest.setIpDstPort(2000); + fixedPcapRequest.setProtocol("tcp"); + fixedPcapRequest.setPacketFilter("filter"); + fixedPcapRequest.setIncludeReverse(true); + MockPcapJob mockPcapJob = new MockPcapJob(); + mockPcapJobSupplier.setMockPcapJob(mockPcapJob); + JobManager jobManager = new InMemoryJobManager<>(); + + PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper)); + FileSystem fileSystem = mock(FileSystem.class); + doReturn(fileSystem).when(pcapService).getFileSystem(); + mockPcapJob.setStatus(new JobStatus() + .withJobId("jobId")); + + pcapService.submit("user", fixedPcapRequest); + + Map<String, Object> configuration = pcapService.getConfiguration("user", "jobId"); + Assert.assertEquals("basePath", PcapOptions.BASE_PATH.get(configuration, String.class)); + Assert.assertEquals("finalOutputPath", PcapOptions.FINAL_OUTPUT_PATH.get(configuration, String.class)); + Assert.assertEquals(1L, PcapOptions.START_TIME_MS.get(configuration, Long.class).longValue()); + Assert.assertEquals(2L, PcapOptions.END_TIME_MS.get(configuration, Long.class).longValue()); + Assert.assertEquals(2, PcapOptions.NUM_REDUCERS.get(configuration, Integer.class).intValue()); + Assert.assertEquals("ip_src_addr", FixedPcapOptions.IP_SRC_ADDR.get(configuration, String.class)); + Assert.assertEquals("ip_dst_addr", FixedPcapOptions.IP_DST_ADDR.get(configuration, String.class)); + Assert.assertEquals(1000, FixedPcapOptions.IP_SRC_PORT.get(configuration, Integer.class).intValue()); + Assert.assertEquals(2000, FixedPcapOptions.IP_DST_PORT.get(configuration, Integer.class).intValue()); + Assert.assertEquals("tcp", FixedPcapOptions.PROTOCOL.get(configuration, String.class)); + Assert.assertEquals("filter", FixedPcapOptions.PACKET_FILTER.get(configuration, String.class)); + Assert.assertEquals(true, FixedPcapOptions.INCLUDE_REVERSE.get(configuration, Boolean.class)); + } + + @Test + public void getConfigurationShouldProperlyReturnQueryFilterConfiguration() throws Exception { + QueryPcapRequest queryPcapRequest = new QueryPcapRequest(); + queryPcapRequest.setBasePath("basePath"); + queryPcapRequest.setBaseInterimResultPath("baseOutputPath"); + queryPcapRequest.setFinalOutputPath("finalOutputPath"); + queryPcapRequest.setStartTimeMs(1L); + queryPcapRequest.setEndTimeMs(2L); + queryPcapRequest.setNumReducers(2); + queryPcapRequest.setQuery("query"); + MockPcapJob mockPcapJob = new MockPcapJob(); + mockPcapJobSupplier.setMockPcapJob(mockPcapJob); + JobManager jobManager = new InMemoryJobManager<>(); + + PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper)); + FileSystem fileSystem = mock(FileSystem.class); + doReturn(fileSystem).when(pcapService).getFileSystem(); + mockPcapJob.setStatus(new JobStatus() + .withJobId("jobId")); + + pcapService.submit("user", queryPcapRequest); + + Map<String, Object> configuration = pcapService.getConfiguration("user", "jobId"); + Assert.assertEquals("basePath", PcapOptions.BASE_PATH.get(configuration, String.class)); + Assert.assertEquals("finalOutputPath", PcapOptions.FINAL_OUTPUT_PATH.get(configuration, String.class)); + Assert.assertEquals(1L, PcapOptions.START_TIME_MS.get(configuration, Long.class).longValue()); + Assert.assertEquals(2L, PcapOptions.END_TIME_MS.get(configuration, Long.class).longValue()); + Assert.assertEquals(2, PcapOptions.NUM_REDUCERS.get(configuration, Integer.class).intValue()); + Assert.assertEquals("query", QueryPcapOptions.QUERY.get(configuration, String.class)); + } + + @Test + public void getConfigurationShouldReturnEmptyMapOnMissingJob() throws Exception { + MockPcapJob mockPcapJob = mock(MockPcapJob.class); + JobManager jobManager = mock(JobManager.class); + doThrow(new JobNotFoundException("Not found test exception.")).when(jobManager).getJob("user", "jobId"); + + PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper); + Map<String, Object> configuration = pcapService.getConfiguration("user", "jobId"); + Assert.assertEquals(new HashMap<>(), configuration); + } + + @Test + public void getConfigurationShouldThrowRestException() throws Exception { + exception.expect(RestException.class); + exception.expectMessage("some job exception"); + + JobManager jobManager = mock(JobManager.class); + when(jobManager.getJob("user", "jobId")).thenThrow(new JobException("some job exception")); + + PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager, pcapToPdmlScriptWrapper); + pcapService.getConfiguration("user", "jobId"); + } + } http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-platform/metron-job/src/main/java/org/apache/metron/job/Statusable.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-job/src/main/java/org/apache/metron/job/Statusable.java b/metron-platform/metron-job/src/main/java/org/apache/metron/job/Statusable.java index 9bdea35..8634b33 100644 --- a/metron-platform/metron-job/src/main/java/org/apache/metron/job/Statusable.java +++ b/metron-platform/metron-job/src/main/java/org/apache/metron/job/Statusable.java @@ -77,4 +77,6 @@ public interface Statusable<PAGE_T> { */ boolean validate(Map<String, Object> configuration); + Map<String, Object> getConfiguration(); + } http://git-wip-us.apache.org/repos/asf/metron/blob/2b6959b4/metron-platform/metron-pcap/src/main/java/org/apache/metron/pcap/mr/PcapJob.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-pcap/src/main/java/org/apache/metron/pcap/mr/PcapJob.java b/metron-platform/metron-pcap/src/main/java/org/apache/metron/pcap/mr/PcapJob.java index a26e5ff..ea2aa29 100644 --- a/metron-platform/metron-pcap/src/main/java/org/apache/metron/pcap/mr/PcapJob.java +++ b/metron-platform/metron-pcap/src/main/java/org/apache/metron/pcap/mr/PcapJob.java @@ -28,6 +28,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -499,4 +500,8 @@ public class PcapJob<T> implements Statusable<Path> { return true; } + @Override + public Map<String, Object> getConfiguration() { + return new HashMap<>(this.configuration); + } }