You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by rm...@apache.org on 2018/07/19 22:13:40 UTC
metron git commit: METRON-1638 Retrieve Pcap results in pdml format
(merrimanr) closes apache/metron#1120
Repository: metron
Updated Branches:
refs/heads/feature/METRON-1554-pcap-query-panel f316d15f0 -> 3e5ef41d9
METRON-1638 Retrieve Pcap results in pdml format (merrimanr) closes apache/metron#1120
Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/3e5ef41d
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/3e5ef41d
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/3e5ef41d
Branch: refs/heads/feature/METRON-1554-pcap-query-panel
Commit: 3e5ef41d9b8639fb1155686e615c02a59b735397
Parents: f316d15
Author: merrimanr <me...@gmail.com>
Authored: Thu Jul 19 17:13:22 2018 -0500
Committer: rmerriman <me...@gmail.com>
Committed: Thu Jul 19 17:13:22 2018 -0500
----------------------------------------------------------------------
dependencies_with_url.csv | 3 +
.../docker/rpm-docker/SPECS/metron.spec | 1 +
metron-interface/metron-rest-client/pom.xml | 5 +
.../apache/metron/rest/model/pcap/Field.java | 164 ++++++++++++
.../apache/metron/rest/model/pcap/Packet.java | 53 ++++
.../org/apache/metron/rest/model/pcap/Pdml.java | 103 ++++++++
.../apache/metron/rest/model/pcap/Proto.java | 114 +++++++++
metron-interface/metron-rest/README.md | 34 ++-
metron-interface/metron-rest/pom.xml | 1 -
.../src/main/config/rest_application.yml | 5 +-
.../apache/metron/rest/MetronRestConstants.java | 1 +
.../apache/metron/rest/config/PcapConfig.java | 6 +
.../metron/rest/controller/PcapController.java | 31 ++-
.../apache/metron/rest/service/PcapService.java | 6 +
.../rest/service/impl/PcapServiceImpl.java | 47 +++-
.../service/impl/PcapToPdmlScriptWrapper.java | 59 +++++
.../src/main/scripts/pcap_to_pdml.sh | 19 ++
.../apache/metron/rest/config/TestConfig.java | 7 +
.../PcapControllerIntegrationTest.java | 65 +++--
.../rest/mock/MockPcapToPdmlScriptWrapper.java | 55 ++++
.../rest/service/impl/PcapServiceImplTest.java | 250 +++++++++++++++++--
metron-interface/pom.xml | 3 +
22 files changed, 981 insertions(+), 51 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/dependencies_with_url.csv
----------------------------------------------------------------------
diff --git a/dependencies_with_url.csv b/dependencies_with_url.csv
index 40d3e06..bf3e382 100644
--- a/dependencies_with_url.csv
+++ b/dependencies_with_url.csv
@@ -141,12 +141,15 @@ com.fasterxml.jackson.dataformat:jackson-dataformat-smile:jar:2.6.6:compile,ASLv
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.6.6:compile,ASLv2,https://github.com/FasterXML/jackson
com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:jar:2.7.4:compile,ASLv2,http://wiki.fasterxml.com/JacksonForCbor
com.fasterxml.jackson.dataformat:jackson-dataformat-smile:jar:2.7.4:compile,ASLv2,http://wiki.fasterxml.com/JacksonForSmile
+com.fasterxml.jackson.dataformat:jackson-dataformat-xml:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.7.4:compile,ASLv2,https://github.com/FasterXML/jackson
com.fasterxml.jackson.datatype:jackson-datatype-joda:jar:2.8.1:compile,ASLv2,https://github.com/FasterXML/jackson-datatype-joda
com.fasterxml.jackson.datatype:jackson-datatype-joda:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson-datatype-joda
com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson-modules-java8
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson-modules-java8
com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson-modules-java8
+com.fasterxml.jackson.module:jackson-module-jaxb-annotations:jar:2.9.5:compile,ASLv2,https://github.com/FasterXML/jackson-modules-java8
+com.fasterxml.woodstox:woodstox-core:jar:5.0.3:compile,ASLv2,https://github.com/FasterXML/woodstox
com.fasterxml:classmate:jar:1.3.1:compile,ASLv2,http://github.com/cowtowncoder/java-classmate
com.fasterxml:classmate:jar:1.3.4:compile,ASLv2,http://github.com/cowtowncoder/java-classmate
com.google.code.gson:gson:jar:2.2.4:compile,The Apache Software License, Version 2.0,http://code.google.com/p/google-gson/
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec b/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
index 4b88fd0..3f090c8 100644
--- a/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
+++ b/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
@@ -419,6 +419,7 @@ This package installs the Metron Rest %{metron_home}
%dir %{metron_home}/lib
%{metron_home}/config/rest_application.yml
%{metron_home}/bin/metron-rest.sh
+%{metron_home}/bin/pcap_to_pdml.sh
%attr(0644,root,root) %{metron_home}/lib/metron-rest-%{full_version}.jar
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest-client/pom.xml
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest-client/pom.xml b/metron-interface/metron-rest-client/pom.xml
index a2f1288..d3fecfd 100644
--- a/metron-interface/metron-rest-client/pom.xml
+++ b/metron-interface/metron-rest-client/pom.xml
@@ -52,6 +52,11 @@
<artifactId>javax.persistence</artifactId>
<version>${eclipse.javax.persistence.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-xml</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Field.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Field.java b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Field.java
new file mode 100644
index 0000000..9c2878b
--- /dev/null
+++ b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Field.java
@@ -0,0 +1,164 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.model.pcap;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Field {
+
+ @JacksonXmlProperty(isAttribute = true)
+ private String name;
+ @JacksonXmlProperty(isAttribute = true)
+ private String pos;
+ @JacksonXmlProperty(isAttribute = true)
+ private String showname;
+ @JacksonXmlProperty(isAttribute = true)
+ private String size;
+ @JacksonXmlProperty(isAttribute = true)
+ private String value;
+ @JacksonXmlProperty(isAttribute = true)
+ private String show;
+ @JacksonXmlProperty(isAttribute = true)
+ private String unmaskedvalue;
+ @JacksonXmlProperty(isAttribute = true)
+ private String hide;
+ @JacksonXmlProperty(localName = "field")
+ @JacksonXmlElementWrapper(useWrapping = false)
+ private List<Field> fields;
+ @JacksonXmlProperty(localName = "proto")
+ @JacksonXmlElementWrapper(useWrapping = false)
+ private List<Proto> protos;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPos() {
+ return pos;
+ }
+
+ public void setPos(String pos) {
+ this.pos = pos;
+ }
+
+ public String getShowname() {
+ return showname;
+ }
+
+ public void setShowname(String showname) {
+ this.showname = showname;
+ }
+
+ public String getSize() {
+ return size;
+ }
+
+ public void setSize(String size) {
+ this.size = size;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getShow() {
+ return show;
+ }
+
+ public void setShow(String show) {
+ this.show = show;
+ }
+
+ public String getUnmaskedvalue() {
+ return unmaskedvalue;
+ }
+
+ public void setUnmaskedvalue(String unmaskedvalue) {
+ this.unmaskedvalue = unmaskedvalue;
+ }
+
+ public String getHide() {
+ return hide;
+ }
+
+ public void setHide(String hide) {
+ this.hide = hide;
+ }
+
+ public List<Field> getFields() {
+ return fields;
+ }
+
+ public void setFields(List<Field> fields) {
+ this.fields = fields;
+ }
+
+ public List<Proto> getProtos() {
+ return protos;
+ }
+
+ public void setProtos(List<Proto> protos) {
+ this.protos = protos;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Field field = (Field) o;
+
+ return (getName() != null ? getName().equals(field.getName()) : field.getName() != null) &&
+ (getPos() != null ? getPos().equals(field.getPos()) : field.getPos() == null) &&
+ (getShowname() != null ? getShowname().equals(field.getShowname()) : field.getShowname() == null) &&
+ (getSize() != null ? getSize().equals(field.getSize()) : field.getSize() == null) &&
+ (getValue() != null ? getValue().equals(field.getValue()) : field.getValue() == null) &&
+ (getShow() != null ? getShow().equals(field.getShow()) : field.getShow() == null) &&
+ (getUnmaskedvalue() != null ? getUnmaskedvalue().equals(field.getUnmaskedvalue()) : field.getUnmaskedvalue() == null) &&
+ (getHide() != null ? getHide().equals(field.getHide()) : field.getHide() == null) &&
+ (getFields() != null ? getFields().equals(field.getFields()) : field.getFields() == null) &&
+ (getProtos() != null ? getProtos().equals(field.getProtos()) : field.getProtos() == null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getName() != null ? getName().hashCode() : 0;
+ result = 31 * result + (getPos() != null ? getPos().hashCode() : 0);
+ result = 31 * result + (getShowname() != null ? getShowname().hashCode() : 0);
+ result = 31 * result + (getSize() != null ? getSize().hashCode() : 0);
+ result = 31 * result + (getValue() != null ? getValue().hashCode() : 0);
+ result = 31 * result + (getShow() != null ? getShow().hashCode() : 0);
+ result = 31 * result + (getUnmaskedvalue() != null ? getUnmaskedvalue().hashCode() : 0);
+ result = 31 * result + (getHide() != null ? getHide().hashCode() : 0);
+ result = 31 * result + (getFields() != null ? getFields().hashCode() : 0);
+ result = 31 * result + (getProtos() != null ? getProtos().hashCode() : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Packet.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Packet.java b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Packet.java
new file mode 100644
index 0000000..de21e6b
--- /dev/null
+++ b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Packet.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.model.pcap;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+import java.util.List;
+
+public class Packet {
+
+ @JacksonXmlProperty(localName = "proto")
+ @JacksonXmlElementWrapper(useWrapping = false)
+ private List<Proto> protos;
+
+ public List<Proto> getProtos() {
+ return protos;
+ }
+
+ public void setProtos(List<Proto> protos) {
+ this.protos = protos;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Packet packet = (Packet) o;
+
+ return (getProtos() != null ? getProtos().equals(packet.getProtos()) : packet.getProtos() == null);
+ }
+
+ @Override
+ public int hashCode() {
+ return getProtos() != null ? getProtos().hashCode() : 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Pdml.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Pdml.java b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Pdml.java
new file mode 100644
index 0000000..f44f96b
--- /dev/null
+++ b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Pdml.java
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.model.pcap;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+import java.util.List;
+
+public class Pdml {
+
+ @JacksonXmlProperty(isAttribute = true)
+ private String version;
+ @JacksonXmlProperty(isAttribute = true)
+ private String creator;
+ @JacksonXmlProperty(isAttribute = true)
+ private String time;
+ @JacksonXmlProperty(isAttribute = true, localName = "capture_file")
+ private String captureFile;
+ @JacksonXmlProperty(localName = "packet")
+ @JacksonXmlElementWrapper(useWrapping = false)
+ private List<Packet> packets;
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getCreator() {
+ return creator;
+ }
+
+ public void setCreator(String creator) {
+ this.creator = creator;
+ }
+
+ public String getTime() {
+ return time;
+ }
+
+ public void setTime(String time) {
+ this.time = time;
+ }
+
+ public String getCaptureFile() {
+ return captureFile;
+ }
+
+ public void setCaptureFile(String captureFile) {
+ this.captureFile = captureFile;
+ }
+
+ public List<Packet> getPackets() {
+ return packets;
+ }
+
+ public void setPackets(List<Packet> packets) {
+ this.packets = packets;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Pdml pdml = (Pdml) o;
+
+ return (getVersion() != null ? getVersion().equals(pdml.getVersion()) : pdml.getVersion() != null) &&
+ (getCreator() != null ? getCreator().equals(pdml.getCreator()) : pdml.getCreator() == null) &&
+ (getTime() != null ? getTime().equals(pdml.getTime()) : pdml.getTime() == null) &&
+ (getCaptureFile() != null ? getCaptureFile().equals(pdml.getCaptureFile()) : pdml.getCaptureFile() == null) &&
+ (getPackets() != null ? getPackets().equals(pdml.getPackets()) : pdml.getPackets() == null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getVersion() != null ? getVersion().hashCode() : 0;
+ result = 31 * result + (getCreator() != null ? getCreator().hashCode() : 0);
+ result = 31 * result + (getTime() != null ? getTime().hashCode() : 0);
+ result = 31 * result + (getCaptureFile() != null ? getCaptureFile().hashCode() : 0);
+ result = 31 * result + (getPackets() != null ? getPackets().hashCode() : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Proto.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Proto.java b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Proto.java
new file mode 100644
index 0000000..bdd5c1f
--- /dev/null
+++ b/metron-interface/metron-rest-client/src/main/java/org/apache/metron/rest/model/pcap/Proto.java
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.model.pcap;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+import java.util.List;
+
+public class Proto {
+
+ @JacksonXmlProperty(isAttribute = true)
+ private String name;
+ @JacksonXmlProperty(isAttribute = true)
+ private String pos;
+ @JacksonXmlProperty(isAttribute = true)
+ private String showname;
+ @JacksonXmlProperty(isAttribute = true)
+ private String size;
+ @JacksonXmlProperty(isAttribute = true)
+ private String hide;
+ @JacksonXmlProperty(localName = "field")
+ @JacksonXmlElementWrapper(useWrapping = false)
+ private List<Field> fields;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPos() {
+ return pos;
+ }
+
+ public void setPos(String pos) {
+ this.pos = pos;
+ }
+
+ public String getShowname() {
+ return showname;
+ }
+
+ public void setShowname(String showname) {
+ this.showname = showname;
+ }
+
+ public String getSize() {
+ return size;
+ }
+
+ public void setSize(String size) {
+ this.size = size;
+ }
+
+ public String getHide() {
+ return hide;
+ }
+
+ public void setHide(String hide) {
+ this.hide = hide;
+ }
+
+ public List<Field> getFields() {
+ return fields;
+ }
+
+ public void setFields(List<Field> fields) {
+ this.fields = fields;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Proto proto = (Proto) o;
+
+ return (getName() != null ? getName().equals(proto.getName()) : proto.getName() != null) &&
+ (getPos() != null ? getPos().equals(proto.getPos()) : proto.getPos() == null) &&
+ (getShowname() != null ? getShowname().equals(proto.getShowname()) : proto.getShowname() == null) &&
+ (getSize() != null ? getSize().equals(proto.getSize()) : proto.getSize() == null) &&
+ (getHide() != null ? getHide().equals(proto.getHide()) : proto.getHide() == null) &&
+ (getFields() != null ? getFields().equals(proto.getFields()) : proto.getFields() == null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getName() != null ? getName().hashCode() : 0;
+ result = 31 * result + (getPos() != null ? getPos().hashCode() : 0);
+ result = 31 * result + (getShowname() != null ? getShowname().hashCode() : 0);
+ result = 31 * result + (getSize() != null ? getSize().hashCode() : 0);
+ result = 31 * result + (getHide() != null ? getHide().hashCode() : 0);
+ result = 31 * result + (getFields() != null ? getFields().hashCode() : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/README.md
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/README.md b/metron-interface/metron-rest/README.md
index 7ccedc8..7b3a263 100644
--- a/metron-interface/metron-rest/README.md
+++ b/metron-interface/metron-rest/README.md
@@ -210,6 +210,17 @@ Setting active profiles is done with the METRON_SPRING_PROFILES_ACTIVE variable.
METRON_SPRING_PROFILES_ACTIVE="vagrant,dev"
```
+## Pcap Query
+
+The REST application exposes endpoints for querying Pcap data. For more information about filtering options see [Query Filter Utility](/metron-platform/metron-pcap-backend#query-filter-utility).
+
+There is an endpoint available that will return Pcap data in [PDML](https://wiki.wireshark.org/PDML) format. [Wireshark](https://www.wireshark.org/) must be installed for this feature to work.
+Installing wireshark in CentOS can be done with `yum -y install wireshark`.
+
+The REST application uses a Java Process object to call out to the `pcap_to_pdml.sh` script. This script is installed at `$METRON_HOME/bin/pcap_to_pdml.sh` by default.
+Out of the box it is a simple wrapper around the tshark command to transform raw pcap data to PDML. However it can be extended to do additional processing as long as the expected input/output is maintained.
+REST will supply the script with raw pcap data through standard in and expects PDML data serialized as XML.
+
## API
Request and Response objects are JSON formatted. The JSON schemas are available in the Swagger UI.
@@ -243,6 +254,8 @@ Request and Response objects are JSON formatted. The JSON schemas are available
| [ `GET /api/v1/metaalert/remove/alert`](#get-apiv1metaalertremovealert)|
| [ `GET /api/v1/metaalert/update/status/{guid}/{status}`](#get-apiv1metaalertupdatestatusguidstatus)|
| [ `GET /api/v1/pcap/fixed`](#get-apiv1pcapfixed)|
+| [ `GET /api/v1/pcap/{jobId}`](#get-apiv1pcapjobid)|
+| [ `GET /api/v1/pcap/{jobId}/pdml`](#get-apiv1pcapjobidpdml)|
| [ `GET /api/v1/search/search`](#get-apiv1searchsearch)|
| [ `POST /api/v1/search/search`](#get-apiv1searchsearch)|
| [ `POST /api/v1/search/group`](#get-apiv1searchgroup)|
@@ -490,9 +503,26 @@ Request and Response objects are JSON formatted. The JSON schemas are available
### `POST /api/v1/pcap/fixed`
* Description: Executes a Fixed Pcap Query.
* Input:
- * fixedPcapRequest - A Fixed Pcap Request which includes fixed filter fields like ip source address and protocol.
+ * fixedPcapRequest - A Fixed Pcap Request which includes fixed filter fields like ip source address and protocol
+ * Returns:
+ * 200 - Returns a job status with job ID.
+
+### `POST /api/v1/pcap/{jobId}`
+ * Description: Gets job status for Pcap query job.
+ * Input:
+ * jobId - Job ID of submitted job
+ * Returns:
+ * 200 - Returns a job status for the Job ID.
+ * 404 - Job is missing.
+
+### `POST /api/v1/pcap/{jobId}/pdml`
+ * Description: Gets Pcap Results for a page in PDML format.
+ * Input:
+ * jobId - Job ID of submitted job
+ * page - Page number
* Returns:
- * 200 - Returns a PcapResponse containing an array of pcaps.
+ * 200 - Returns PDML in json format.
+ * 404 - Job or page 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/3e5ef41d/metron-interface/metron-rest/pom.xml
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/pom.xml b/metron-interface/metron-rest/pom.xml
index 733ef6a..1bf0fd6 100644
--- a/metron-interface/metron-rest/pom.xml
+++ b/metron-interface/metron-rest/pom.xml
@@ -36,7 +36,6 @@
<spring-kafka.version>2.0.4.RELEASE</spring-kafka.version>
<spring.version>5.0.5.RELEASE</spring.version>
<eclipse.link.version>2.6.4</eclipse.link.version>
- <jackson.version>2.9.5</jackson.version>
<jsonpath.version>2.4.0</jsonpath.version>
</properties>
<dependencies>
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/main/config/rest_application.yml
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/main/config/rest_application.yml b/metron-interface/metron-rest/src/main/config/rest_application.yml
index 4cc51ff..3999393 100644
--- a/metron-interface/metron-rest/src/main/config/rest_application.yml
+++ b/metron-interface/metron-rest/src/main/config/rest_application.yml
@@ -52,4 +52,7 @@ storm:
kerberos:
enabled: ${SECURITY_ENABLED}
principal: ${METRON_PRINCIPAL_NAME}
- keytab: ${METRON_SERVICE_KEYTAB}
\ No newline at end of file
+ keytab: ${METRON_SERVICE_KEYTAB}
+
+pcap:
+ pdml.script.path: ${METRON_HOME}/bin/pcap_to_pdml.sh
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
index 8e14e38..b65d037 100644
--- a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
+++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
@@ -79,4 +79,5 @@ public class MetronRestConstants {
public static final String PCAP_BASE_INTERIM_RESULT_PATH_SPRING_PROPERTY = "pcap.base.interim.result.path";
public static final String PCAP_FINAL_OUTPUT_PATH_SPRING_PROPERTY = "pcap.final.output.path";
public static final String PCAP_PAGE_SIZE_SPRING_PROPERTY = "pcap.page.size";
+ public static final String PCAP_PDML_SCRIPT_PATH_SPRING_PROPERTY = "pcap.pdml.script.path";
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/PcapConfig.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/PcapConfig.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/PcapConfig.java
index a0b7f18..323df05 100644
--- a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/PcapConfig.java
+++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/PcapConfig.java
@@ -19,6 +19,7 @@ package org.apache.metron.rest.config;
import org.apache.metron.job.manager.InMemoryJobManager;
import org.apache.metron.job.manager.JobManager;
+import org.apache.metron.rest.service.impl.PcapToPdmlScriptWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@@ -39,5 +40,10 @@ public class PcapConfig {
return new PcapJobSupplier();
}
+ @Bean
+ public PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper() {
+ return new PcapToPdmlScriptWrapper();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/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 6663659..47bc6a0 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
@@ -24,6 +24,7 @@ import io.swagger.annotations.ApiResponses;
import org.apache.metron.rest.RestException;
import org.apache.metron.rest.model.pcap.FixedPcapRequest;
import org.apache.metron.rest.model.pcap.PcapStatus;
+import org.apache.metron.rest.model.pcap.Pdml;
import org.apache.metron.rest.security.SecurityUtils;
import org.apache.metron.rest.service.PcapService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +34,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@@ -46,16 +48,18 @@ public class PcapController {
@ApiResponses(value = { @ApiResponse(message = "Returns a job status with job ID.", code = 200)})
@RequestMapping(value = "/fixed", method = RequestMethod.POST)
ResponseEntity<PcapStatus> fixed(@ApiParam(name="fixedPcapRequest", value="A Fixed Pcap Request"
- + " which includes fixed filter fields like ip source address and protocol.", required=true)@RequestBody FixedPcapRequest fixedPcapRequest) throws RestException {
+ + " which includes fixed filter fields like ip source address and protocol", required=true)@RequestBody FixedPcapRequest fixedPcapRequest) throws RestException {
PcapStatus pcapStatus = pcapQueryService.fixed(SecurityUtils.getCurrentUser(), fixedPcapRequest);
return new ResponseEntity<>(pcapStatus, HttpStatus.OK);
}
- @ApiOperation(value = "Gets job status for running job.")
- @ApiResponses(value = { @ApiResponse(message = "Returns a job status for the passed job.", code = 200)})
+ @ApiOperation(value = "Gets job status for Pcap query job.")
+ @ApiResponses(value = {
+ @ApiResponse(message = "Returns a job status for the Job ID.", code = 200),
+ @ApiResponse(message = "Job is missing.", code = 404)
+ })
@RequestMapping(value = "/{jobId}", method = RequestMethod.GET)
- ResponseEntity<PcapStatus> getStatus(@ApiParam(name="jobId", value="Job ID of submitted job"
- + " which includes fixed filter fields like ip source address and protocol.", required=true)@PathVariable String jobId) throws RestException {
+ ResponseEntity<PcapStatus> getStatus(@ApiParam(name="jobId", value="Job ID of submitted job", required=true)@PathVariable String jobId) throws RestException {
PcapStatus jobStatus = pcapQueryService.getJobStatus(SecurityUtils.getCurrentUser(), jobId);
if (jobStatus != null) {
return new ResponseEntity<>(jobStatus, HttpStatus.OK);
@@ -64,6 +68,23 @@ public class PcapController {
}
}
+ @ApiOperation(value = "Gets Pcap Results for a page in PDML format.")
+ @ApiResponses(value = {
+ @ApiResponse(message = "Returns PDML in json format.", code = 200),
+ @ApiResponse(message = "Job or page is missing.", code = 404)
+ })
+ @RequestMapping(value = "/{jobId}/pdml", method = RequestMethod.GET)
+ ResponseEntity<Pdml> pdml(@ApiParam(name="jobId", value="Job ID of submitted job", required=true)@PathVariable String jobId,
+ @ApiParam(name="page", value="Page number", required=true)@RequestParam Integer page) throws RestException {
+ Pdml pdml = pcapQueryService.getPdml(SecurityUtils.getCurrentUser(), jobId, page);
+ if (pdml != null) {
+ return new ResponseEntity<>(pdml, HttpStatus.OK);
+ } else {
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ }
+
+
@ApiOperation(value = "Kills running job.")
@ApiResponses(value = { @ApiResponse(message = "Kills passed job.", code = 200)})
@RequestMapping(value = "/kill/{jobId}", method = RequestMethod.DELETE)
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/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 8073573..9421ce3 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
@@ -17,9 +17,12 @@
*/
package org.apache.metron.rest.service;
+import org.apache.hadoop.fs.Path;
import org.apache.metron.rest.RestException;
import org.apache.metron.rest.model.pcap.FixedPcapRequest;
import org.apache.metron.rest.model.pcap.PcapStatus;
+import org.apache.metron.rest.model.pcap.Pdml;
+import org.apache.metron.rest.model.pcap.Pdml;
public interface PcapService {
@@ -29,4 +32,7 @@ public interface PcapService {
PcapStatus killJob(String username, String jobId) throws RestException;
+ Path getPath(String username, String jobId, Integer page) throws RestException;
+
+ Pdml getPdml(String username, String jobId, Integer page) throws RestException;
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/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 6c21e77..7894b1a 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
@@ -17,7 +17,7 @@
*/
package org.apache.metron.rest.service.impl;
-import java.io.IOException;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
@@ -34,11 +34,15 @@ import org.apache.metron.rest.config.PcapJobSupplier;
import org.apache.metron.rest.model.pcap.FixedPcapRequest;
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.service.PcapService;
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;
+
@Service
public class PcapServiceImpl implements PcapService {
@@ -46,13 +50,15 @@ public class PcapServiceImpl implements PcapService {
private Configuration configuration;
private PcapJobSupplier pcapJobSupplier;
private JobManager<Path> jobManager;
+ private PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper;
@Autowired
- public PcapServiceImpl(Environment environment, Configuration configuration, PcapJobSupplier pcapJobSupplier, JobManager<Path> jobManager) {
+ public PcapServiceImpl(Environment environment, Configuration configuration, PcapJobSupplier pcapJobSupplier, JobManager<Path> jobManager, PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper) {
this.environment = environment;
this.configuration = configuration;
this.pcapJobSupplier = pcapJobSupplier;
this.jobManager = jobManager;
+ this.pcapToPdmlScriptWrapper = pcapToPdmlScriptWrapper;
}
@Override
@@ -103,6 +109,43 @@ public class PcapServiceImpl implements PcapService {
return getJobStatus(username, jobId);
}
+ @Override
+ public Path getPath(String username, String jobId, Integer page) throws RestException {
+ Path path = null;
+ try {
+ Statusable<Path> statusable = jobManager.getJob(username, jobId);
+ if (statusable != null && statusable.isDone()) {
+ Pageable<Path> pageable = statusable.get();
+ if (pageable != null && page <= pageable.getSize() && page > 0) {
+ path = pageable.getPage(page - 1);
+ }
+ }
+ } catch (JobNotFoundException e) {
+ // do nothing and return null pcapStatus
+ } catch (JobException | InterruptedException e) {
+ throw new RestException(e);
+ }
+ return path;
+ }
+
+ @Override
+ public Pdml getPdml(String username, String jobId, Integer page) throws RestException {
+ Pdml pdml = null;
+ Path path = getPath(username, jobId, page);
+ try {
+ FileSystem fileSystem = getFileSystem();
+ if (path!= null && fileSystem.exists(path)) {
+ String scriptPath = environment.getProperty(MetronRestConstants.PCAP_PDML_SCRIPT_PATH_SPRING_PROPERTY);
+ InputStream processInputStream = pcapToPdmlScriptWrapper.execute(scriptPath, fileSystem, path);
+ pdml = new XmlMapper().readValue(processInputStream, Pdml.class);
+ processInputStream.close();
+ }
+ } catch (IOException e) {
+ throw new RestException(e);
+ }
+ return pdml;
+ }
+
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/3e5ef41d/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapToPdmlScriptWrapper.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapToPdmlScriptWrapper.java b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapToPdmlScriptWrapper.java
new file mode 100644
index 0000000..b5e3033
--- /dev/null
+++ b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/service/impl/PcapToPdmlScriptWrapper.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.service.impl;
+
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.apache.commons.io.IOUtils;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.metron.rest.MetronRestConstants;
+import org.apache.metron.rest.RestException;
+import org.apache.metron.rest.model.pcap.Pdml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+public class PcapToPdmlScriptWrapper {
+
+ public InputStream execute(String scriptPath, FileSystem fileSystem, Path pcapPath) throws IOException {
+ ProcessBuilder processBuilder = getProcessBuilder(scriptPath, pcapPath.toUri().getPath());
+ Process process = processBuilder.start();
+ InputStream rawInputStream = getRawInputStream(fileSystem, pcapPath);
+ OutputStream processOutputStream = process.getOutputStream();
+ IOUtils.copy(rawInputStream, processOutputStream);
+ rawInputStream.close();
+ if (process.isAlive()) {
+ // need to close processOutputStream if script doesn't exit with an error
+ processOutputStream.close();
+ return process.getInputStream();
+ } else {
+ String errorMessage = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8);
+ throw new IOException(errorMessage);
+ }
+ }
+
+ protected InputStream getRawInputStream(FileSystem fileSystem, Path path) throws IOException {
+ return fileSystem.open(path);
+ }
+
+ protected ProcessBuilder getProcessBuilder(String... command) {
+ return new ProcessBuilder(command);
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/main/scripts/pcap_to_pdml.sh
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/main/scripts/pcap_to_pdml.sh b/metron-interface/metron-rest/src/main/scripts/pcap_to_pdml.sh
new file mode 100755
index 0000000..81c3781
--- /dev/null
+++ b/metron-interface/metron-rest/src/main/scripts/pcap_to_pdml.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+tshark -i - -T pdml
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/config/TestConfig.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/config/TestConfig.java b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/config/TestConfig.java
index a5a0236..942ff78 100644
--- a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/config/TestConfig.java
+++ b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/config/TestConfig.java
@@ -51,8 +51,10 @@ import org.apache.metron.job.manager.JobManager;
import org.apache.metron.rest.RestException;
import org.apache.metron.rest.mock.MockPcapJob;
import org.apache.metron.rest.mock.MockPcapJobSupplier;
+import org.apache.metron.rest.mock.MockPcapToPdmlScriptWrapper;
import org.apache.metron.rest.mock.MockStormCLIClientWrapper;
import org.apache.metron.rest.mock.MockStormRestTemplate;
+import org.apache.metron.rest.service.impl.PcapToPdmlScriptWrapper;
import org.apache.metron.rest.service.impl.StormCLIWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -205,4 +207,9 @@ public class TestConfig {
mockPcapJobSupplier.setMockPcapJob(mockPcapJob);
return mockPcapJobSupplier;
}
+
+ @Bean
+ public PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper() {
+ return new MockPcapToPdmlScriptWrapper();
+ }
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/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 2363204..2fa64cd 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
@@ -183,9 +183,6 @@ public class PcapControllerIntegrationTest {
public void testGetStatus() throws Exception {
MockPcapJob mockPcapJob = (MockPcapJob) wac.getBean("mockPcapJob");
- this.mockMvc.perform(get(pcapUrl + "/jobId").with(httpBasic(user, password)))
- .andExpect(status().isNotFound());
-
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))
@@ -226,6 +223,9 @@ public class PcapControllerIntegrationTest {
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(jsonPath("$.jobStatus").value("KILLED"));
+
+ this.mockMvc.perform(get(pcapUrl + "/someJobId").with(httpBasic(user, password)))
+ .andExpect(status().isNotFound());
}
@Test
@@ -233,23 +233,23 @@ public class PcapControllerIntegrationTest {
MockPcapJob mockPcapJob = (MockPcapJob) wac.getBean("mockPcapJob");
this.mockMvc.perform(get(pcapUrl + "/jobId123").with(httpBasic(user, password)))
- .andExpect(status().isNotFound());
+ .andExpect(status().isNotFound());
mockPcapJob.setStatus(new JobStatus().withJobId("jobId123").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("jobId123"))
- .andExpect(jsonPath("$.jobStatus").value("RUNNING"));
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")))
+ .andExpect(jsonPath("$.jobId").value("jobId123"))
+ .andExpect(jsonPath("$.jobStatus").value("RUNNING"));
mockPcapJob.setStatus(new JobStatus().withJobId("jobId123").withState(JobStatus.State.KILLED));
this.mockMvc.perform(delete(pcapUrl + "/kill/{id}", "jobId123").with(httpBasic(user, password)))
- .andExpect(status().isOk())
- .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")))
- .andExpect(jsonPath("$.jobId").value("jobId123"))
- .andExpect(jsonPath("$.jobStatus").value("KILLED"));
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")))
+ .andExpect(jsonPath("$.jobId").value("jobId123"))
+ .andExpect(jsonPath("$.jobStatus").value("KILLED"));
mockPcapJob.setStatus(new JobStatus().withJobId("jobId").withState(JobStatus.State.KILLED));
}
@@ -259,10 +259,47 @@ public class PcapControllerIntegrationTest {
MockPcapJob mockPcapJob = (MockPcapJob) wac.getBean("mockPcapJob");
this.mockMvc.perform(get(pcapUrl + "/jobId123").with(httpBasic(user, password)))
- .andExpect(status().isNotFound());
+ .andExpect(status().isNotFound());
this.mockMvc.perform(delete(pcapUrl + "/kill/{id}", "jobId123").with(httpBasic(user, password)))
- .andExpect(status().isNotFound());
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ public void testGetPdml() 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"));
+
+ Pageable<Path> pageable = new PcapPages(Arrays.asList(new Path("./target")));
+ mockPcapJob.setIsDone(true);
+ mockPcapJob.setPageable(pageable);
+
+ this.mockMvc.perform(get(pcapUrl + "/jobId/pdml?page=1").with(httpBasic(user, password)))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")))
+ .andExpect(jsonPath("$.version").value("0"))
+ .andExpect(jsonPath("$.creator").value("wireshark/2.6.1"))
+ .andExpect(jsonPath("$.time").value("Thu Jun 28 14:14:38 2018"))
+ .andExpect(jsonPath("$.captureFile").value("/tmp/pcap-data-201806272004-289365c53112438ca55ea047e13a12a5+0001.pcap"))
+ .andExpect(jsonPath("$.packets[0].protos[0].name").value("geninfo"))
+ .andExpect(jsonPath("$.packets[0].protos[0].fields[0].name").value("num"))
+ .andExpect(jsonPath("$.packets[0].protos[1].name").value("ip"))
+ .andExpect(jsonPath("$.packets[0].protos[1].fields[0].name").value("ip.addr"))
+ ;
+
+ this.mockMvc.perform(get(pcapUrl + "/jobId/pdml?page=0").with(httpBasic(user, password)))
+ .andExpect(status().isNotFound());
+
+ this.mockMvc.perform(get(pcapUrl + "/jobId/pdml?page=2").with(httpBasic(user, password)))
+ .andExpect(status().isNotFound());
}
+
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapToPdmlScriptWrapper.java
----------------------------------------------------------------------
diff --git a/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapToPdmlScriptWrapper.java b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapToPdmlScriptWrapper.java
new file mode 100644
index 0000000..940648c
--- /dev/null
+++ b/metron-interface/metron-rest/src/test/java/org/apache/metron/rest/mock/MockPcapToPdmlScriptWrapper.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.metron.rest.mock;
+
+import org.adrianwalker.multilinestring.Multiline;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.metron.rest.service.impl.PcapToPdmlScriptWrapper;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class MockPcapToPdmlScriptWrapper extends PcapToPdmlScriptWrapper {
+
+ /**
+ *<?xml version="1.0" encoding="utf-8"?>
+ *<?xml-stylesheet type="text/xsl" href="pdml2html.xsl"?>
+ *<pdml version="0" creator="wireshark/2.6.1" time="Thu Jun 28 14:14:38 2018" capture_file="/tmp/pcap-data-201806272004-289365c53112438ca55ea047e13a12a5+0001.pcap">
+ *<packet>
+ *<proto name="geninfo" pos="0" showname="General information" size="722" hide="no">
+ *<field name="num" pos="0" show="1" showname="Number" value="1" size="722"/>
+ *</proto>
+ *<proto name="ip" showname="Internet Protocol Version 4, Src: 192.168.66.1, Dst: 192.168.66.121" size="20" pos="14" hide="yes">
+ *<field name="ip.addr" showname="Source or Destination Address: 192.168.66.121" hide="yes" size="4" pos="30" show="192.168.66.121" value="c0a84279"/>
+ *<field name="ip.flags" showname="Flags: 0x4000, Don't fragment" size="2" pos="20" show="0x00004000" value="4000">
+ *<field name="ip.flags.mf" showname="..0. .... .... .... = More fragments: Not set" size="2" pos="20" show="0" value="0" unmaskedvalue="4000"/>
+ *</field>
+ *</proto>
+ *</packet>
+ *</pdml>
+ */
+ @Multiline
+ private String pdmlXml;
+
+ @Override
+ public InputStream execute(String scriptPath, FileSystem fileSystem, Path pcapPath) throws IOException {
+ return new ByteArrayInputStream(pdmlXml.getBytes());
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/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 8b628b3..d818c77 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
@@ -17,25 +17,15 @@
*/
package org.apache.metron.rest.service.impl;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.powermock.api.mockito.PowerMockito.doReturn;
-
-import java.util.HashMap;
-import java.util.Map;
+import org.adrianwalker.multilinestring.Multiline;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
import org.apache.metron.common.Constants;
+import org.apache.metron.common.utils.JSONUtils;
import org.apache.metron.job.JobException;
import org.apache.metron.job.JobNotFoundException;
import org.apache.metron.job.JobStatus;
-import org.apache.metron.job.JobStatus.State;
import org.apache.metron.job.Pageable;
import org.apache.metron.job.manager.InMemoryJobManager;
import org.apache.metron.job.manager.JobManager;
@@ -48,33 +38,154 @@ import org.apache.metron.rest.mock.MockPcapJob;
import org.apache.metron.rest.mock.MockPcapJobSupplier;
import org.apache.metron.rest.model.pcap.FixedPcapRequest;
import org.apache.metron.rest.model.pcap.PcapStatus;
+import org.apache.metron.rest.model.pcap.Pdml;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.core.env.Environment;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyVararg;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.doReturn;
+import static org.powermock.api.mockito.PowerMockito.whenNew;
+
@SuppressWarnings("ALL")
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({PcapToPdmlScriptWrapper.class, ProcessBuilder.class})
public class PcapServiceImplTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
+ /**
+ *<?xml version="1.0" encoding="utf-8"?>
+ *<?xml-stylesheet type="text/xsl" href="pdml2html.xsl"?>
+ *<pdml version="0" creator="wireshark/2.6.1" time="Thu Jun 28 14:14:38 2018" capture_file="/tmp/pcap-data-201806272004-289365c53112438ca55ea047e13a12a5+0001.pcap">
+ *<packet>
+ *<proto name="geninfo" pos="0" showname="General information" size="722" hide="no">
+ *<field name="num" pos="0" show="1" showname="Number" value="1" size="722"/>
+ *</proto>
+ *<proto name="ip" showname="Internet Protocol Version 4, Src: 192.168.66.1, Dst: 192.168.66.121" size="20" pos="14" hide="yes">
+ *<field name="ip.addr" showname="Source or Destination Address: 192.168.66.121" hide="yes" size="4" pos="30" show="192.168.66.121" value="c0a84279"/>
+ *<field name="ip.flags" showname="Flags: 0x4000, Don't fragment" size="2" pos="20" show="0x00004000" value="4000">
+ *<field name="ip.flags.mf" showname="..0. .... .... .... = More fragments: Not set" size="2" pos="20" show="0" value="0" unmaskedvalue="4000"/>
+ *</field>
+ *</proto>
+ *</packet>
+ *</pdml>
+ */
+ @Multiline
+ private String pdmlXml;
+
+ /**
+ *{
+ "version": "0",
+ "creator": "wireshark/2.6.1",
+ "time": "Thu Jun 28 14:14:38 2018",
+ "captureFile": "/tmp/pcap-data-201806272004-289365c53112438ca55ea047e13a12a5+0001.pcap",
+ "packets": [
+ {
+ "protos": [
+ {
+ "name": "geninfo",
+ "pos": "0",
+ "showname": "General information",
+ "size": "722",
+ "hide": "no",
+ "fields": [
+ {
+ "name": "num",
+ "pos": "0",
+ "showname": "Number",
+ "size": "722",
+ "value": "1",
+ "show": "1"
+ }
+ ]
+ },
+ {
+ "name": "ip",
+ "pos": "14",
+ "showname": "Internet Protocol Version 4, Src: 192.168.66.1, Dst: 192.168.66.121",
+ "size": "20",
+ "hide": "yes",
+ "fields": [
+ {
+ "name": "ip.addr",
+ "pos": "30",
+ "showname": "Source or Destination Address: 192.168.66.121",
+ "size": "4",
+ "value": "c0a84279",
+ "show": "192.168.66.121",
+ "hide": "yes"
+ },
+ {
+ "name": "ip.flags",
+ "pos": "20",
+ "showname": "Flags: 0x4000, Don't fragment",
+ "size": "2",
+ "value": "4000",
+ "show": "0x00004000",
+ "fields": [
+ {
+ "name": "ip.flags.mf",
+ "pos": "20",
+ "showname": "..0. .... .... .... = More fragments: Not set",
+ "size": "2",
+ "value": "0",
+ "show": "0",
+ "unmaskedvalue": "4000"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ */
+ @Multiline
+ private String expectedPdml;
+
Environment environment;
Configuration configuration;
MockPcapJobSupplier mockPcapJobSupplier;
+ PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper;
@Before
public void setUp() throws Exception {
environment = mock(Environment.class);
configuration = mock(Configuration.class);
mockPcapJobSupplier = new MockPcapJobSupplier();
+ pcapToPdmlScriptWrapper = new PcapToPdmlScriptWrapper();
when(environment.getProperty(MetronRestConstants.PCAP_BASE_PATH_SPRING_PROPERTY)).thenReturn("/base/path");
when(environment.getProperty(MetronRestConstants.PCAP_BASE_INTERIM_RESULT_PATH_SPRING_PROPERTY)).thenReturn("/base/interim/result/path");
when(environment.getProperty(MetronRestConstants.PCAP_FINAL_OUTPUT_PATH_SPRING_PROPERTY)).thenReturn("/final/output/path");
when(environment.getProperty(MetronRestConstants.PCAP_PAGE_SIZE_SPRING_PROPERTY)).thenReturn("100");
+ when(environment.getProperty(MetronRestConstants.PCAP_PDML_SCRIPT_PATH_SPRING_PROPERTY)).thenReturn("/path/to/pdml/script");
}
@Test
@@ -97,7 +208,7 @@ public class PcapServiceImplTest {
mockPcapJobSupplier.setMockPcapJob(mockPcapJob);
JobManager jobManager = new InMemoryJobManager<>();
- PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager));
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper));
FileSystem fileSystem = mock(FileSystem.class);
doReturn(fileSystem).when(pcapService).getFileSystem();
mockPcapJob.setStatus(new JobStatus()
@@ -149,7 +260,7 @@ public class PcapServiceImplTest {
mockPcapJobSupplier.setMockPcapJob(mockPcapJob);
JobManager jobManager = new InMemoryJobManager<>();
- PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager));
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper));
FileSystem fileSystem = mock(FileSystem.class);
doReturn(fileSystem).when(pcapService).getFileSystem();
mockPcapJob.setStatus(new JobStatus()
@@ -184,7 +295,7 @@ public class PcapServiceImplTest {
FixedPcapRequest fixedPcapRequest = new FixedPcapRequest();
JobManager jobManager = mock(JobManager.class);
PcapJobSupplier pcapJobSupplier = new PcapJobSupplier();
- PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, pcapJobSupplier, jobManager));
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, pcapJobSupplier, jobManager, pcapToPdmlScriptWrapper));
FileSystem fileSystem = mock(FileSystem.class);
doReturn(fileSystem).when(pcapService).getFileSystem();
when(jobManager.submit(pcapJobSupplier, "user")).thenThrow(new JobException("some job exception"));
@@ -208,7 +319,7 @@ public class PcapServiceImplTest {
when(mockPcapJob.get()).thenReturn(pageable);
when(jobManager.getJob("user", "jobId")).thenReturn(mockPcapJob);
- PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper);
PcapStatus expectedPcapStatus = new PcapStatus();
expectedPcapStatus.setJobId("jobId");
expectedPcapStatus.setJobStatus(JobStatus.State.SUCCEEDED.name());
@@ -222,7 +333,7 @@ public class PcapServiceImplTest {
@Test
public void getStatusShouldReturnNullOnMissingStatus() throws Exception {
JobManager jobManager = new InMemoryJobManager();
- PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager, pcapToPdmlScriptWrapper);
Assert.assertNull(pcapService.getJobStatus("user", "jobId"));
}
@@ -235,7 +346,7 @@ public class PcapServiceImplTest {
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);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager, pcapToPdmlScriptWrapper);
pcapService.getJobStatus("user", "jobId");
}
@@ -244,10 +355,10 @@ public class PcapServiceImplTest {
MockPcapJob mockPcapJob = mock(MockPcapJob.class);
JobManager jobManager = mock(JobManager.class);
JobStatus actualJobStatus = new JobStatus()
- .withJobId("jobId")
- .withState(State.KILLED)
- .withDescription("description")
- .withPercentComplete(100.0);
+ .withJobId("jobId")
+ .withState(JobStatus.State.KILLED)
+ .withDescription("description")
+ .withPercentComplete(100.0);
Pageable pageable = mock(Pageable.class);
when(pageable.getSize()).thenReturn(0);
when(mockPcapJob.getStatus()).thenReturn(actualJobStatus);
@@ -255,10 +366,10 @@ public class PcapServiceImplTest {
when(mockPcapJob.get()).thenReturn(pageable);
when(jobManager.getJob("user", "jobId")).thenReturn(mockPcapJob);
- PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper);
PcapStatus status = pcapService.killJob("user", "jobId");
verify(jobManager, times(1)).killJob("user", "jobId");
- assertThat(status.getJobStatus(), CoreMatchers.equalTo(State.KILLED.toString()));
+ assertThat(status.getJobStatus(), CoreMatchers.equalTo(JobStatus.State.KILLED.toString()));
}
@Test
@@ -267,10 +378,97 @@ public class PcapServiceImplTest {
JobManager jobManager = mock(JobManager.class);
doThrow(new JobNotFoundException("Not found test exception.")).when(jobManager).killJob("user", "jobId");
- PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, mockPcapJobSupplier, jobManager, pcapToPdmlScriptWrapper);
PcapStatus status = pcapService.killJob("user", "jobId");
verify(jobManager, times(1)).killJob("user", "jobId");
assertNull(status);
}
+ @Test
+ public void getPathShouldProperlyReturnPath() throws Exception {
+ Path actualPath = new Path("/path");
+ MockPcapJob mockPcapJob = mock(MockPcapJob.class);
+ JobManager jobManager = mock(JobManager.class);
+ Pageable pageable = mock(Pageable.class);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager, pcapToPdmlScriptWrapper);
+
+ when(pageable.getSize()).thenReturn(2);
+ when(mockPcapJob.isDone()).thenReturn(true);
+ when(mockPcapJob.get()).thenReturn(pageable);
+ when(pageable.getPage(0)).thenReturn(actualPath);
+ when(jobManager.getJob("user", "jobId")).thenReturn(mockPcapJob);
+
+ Assert.assertEquals("/path", pcapService.getPath("user", "jobId", 1).toUri().getPath());
+ }
+
+ @Test
+ public void getPathShouldReturnNullOnInvalidPageSize() throws Exception {
+ MockPcapJob mockPcapJob = mock(MockPcapJob.class);
+ JobManager jobManager = mock(JobManager.class);
+ Pageable pageable = mock(Pageable.class);
+ PcapServiceImpl pcapService = new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), jobManager, pcapToPdmlScriptWrapper);
+
+ when(pageable.getSize()).thenReturn(2);
+ when(mockPcapJob.isDone()).thenReturn(true);
+ when(mockPcapJob.get()).thenReturn(pageable);
+ when(jobManager.getJob("user", "jobId")).thenReturn(mockPcapJob);
+
+ Assert.assertNull(pcapService.getPath("user", "jobId", 0));
+ Assert.assertNull(pcapService.getPath("user", "jobId", 3));
+ }
+
+ @Test
+ public void getPdmlShouldGetPdml() throws Exception {
+ Path path = new Path("./target");
+ PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper = spy(new PcapToPdmlScriptWrapper());
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), new InMemoryJobManager<>(), pcapToPdmlScriptWrapper));
+ FileSystem fileSystem = mock(FileSystem.class);
+ doReturn(fileSystem).when(pcapService).getFileSystem();
+ when(fileSystem.exists(path)).thenReturn(true);
+ doReturn(path).when(pcapService).getPath("user", "jobId", 1);
+ doReturn(new ByteArrayInputStream(pdmlXml.getBytes())).when(pcapToPdmlScriptWrapper).getRawInputStream(fileSystem, path);
+ ProcessBuilder pb = PowerMockito.mock(ProcessBuilder.class);
+ Process p = PowerMockito.mock(Process.class);
+ OutputStream outputStream = new ByteArrayOutputStream();
+ when(p.getOutputStream()).thenReturn(outputStream);
+ when(p.isAlive()).thenReturn(true);
+ when(p.getInputStream()).thenReturn(new ByteArrayInputStream(pdmlXml.getBytes()));
+ whenNew(ProcessBuilder.class).withParameterTypes(String[].class).withArguments(anyVararg()).thenReturn(pb);
+ PowerMockito.when(pb.start()).thenReturn(p);
+
+ assertEquals(JSONUtils.INSTANCE.load(expectedPdml, Pdml.class), pcapService.getPdml("user", "jobId", 1));
+ }
+
+ @Test
+ public void getPdmlShouldReturnNullOnNonexistentPath() throws Exception {
+ Path path = new Path("/some/path");
+
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), new InMemoryJobManager<>(), pcapToPdmlScriptWrapper));
+ FileSystem fileSystem = mock(FileSystem.class);
+ doReturn(fileSystem).when(pcapService).getFileSystem();
+ when(fileSystem.exists(path)).thenReturn(false);
+ doReturn(path).when(pcapService).getPath("user", "jobId", 1);
+
+ assertNull(pcapService.getPdml("user", "jobId", 1));
+ }
+
+ @Test
+ public void getPdmlShouldThrowException() throws Exception {
+ exception.expect(RestException.class);
+ exception.expectMessage("some exception");
+
+ Path path = new Path("./target");
+ PcapToPdmlScriptWrapper pcapToPdmlScriptWrapper = spy(new PcapToPdmlScriptWrapper());
+ PcapServiceImpl pcapService = spy(new PcapServiceImpl(environment, configuration, new PcapJobSupplier(), new InMemoryJobManager<>(), pcapToPdmlScriptWrapper));
+ FileSystem fileSystem = mock(FileSystem.class);
+ doReturn(fileSystem).when(pcapService).getFileSystem();
+ when(fileSystem.exists(path)).thenReturn(true);
+ doReturn(path).when(pcapService).getPath("user", "jobId", 1);
+ ProcessBuilder pb = PowerMockito.mock(ProcessBuilder.class);
+ doReturn(pb).when(pcapToPdmlScriptWrapper).getProcessBuilder("/path/to/pdml/script", "target");
+ PowerMockito.when(pb.start()).thenThrow(new IOException("some exception"));
+
+ pcapService.getPdml("user", "jobId", 1);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/metron/blob/3e5ef41d/metron-interface/pom.xml
----------------------------------------------------------------------
diff --git a/metron-interface/pom.xml b/metron-interface/pom.xml
index e6ccd2d..c8f863c 100644
--- a/metron-interface/pom.xml
+++ b/metron-interface/pom.xml
@@ -25,6 +25,9 @@
</parent>
<description>Interfaces for Metron</description>
<url>https://metron.apache.org/</url>
+ <properties>
+ <jackson.version>2.9.5</jackson.version>
+ </properties>
<scm>
<connection>scm:git:https://git-wip-us.apache.org/repos/asf/metron.git</connection>
<developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/metron.git</developerConnection>