some logging changes, test improvements, style check

This commit is contained in:
bhlowe
2019-07-31 10:24:56 -07:00
parent 1c7c05710e
commit 77d1c615eb
17 changed files with 1323 additions and 1293 deletions

View File

@@ -2,222 +2,222 @@
<code_scheme name="GoogleStyle"> <code_scheme name="GoogleStyle">
<option name="OTHER_INDENT_OPTIONS"> <option name="OTHER_INDENT_OPTIONS">
<value> <value>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
<option name="USE_TAB_CHARACTER" value="false" /> <option name="USE_TAB_CHARACTER" value="false"/>
<option name="SMART_TABS" value="false" /> <option name="SMART_TABS" value="false"/>
<option name="LABEL_INDENT_SIZE" value="0" /> <option name="LABEL_INDENT_SIZE" value="0"/>
<option name="LABEL_INDENT_ABSOLUTE" value="false" /> <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
<option name="USE_RELATIVE_INDENTS" value="false" /> <option name="USE_RELATIVE_INDENTS" value="false"/>
</value> </value>
</option> </option>
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" /> <option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND"> <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value /> <value/>
</option> </option>
<option name="IMPORT_LAYOUT_TABLE"> <option name="IMPORT_LAYOUT_TABLE">
<value> <value>
<package name="" withSubpackages="true" static="true" /> <package name="" withSubpackages="true" static="true"/>
<emptyLine /> <emptyLine/>
<package name="" withSubpackages="true" static="false" /> <package name="" withSubpackages="true" static="false"/>
</value> </value>
</option> </option>
<option name="RIGHT_MARGIN" value="100" /> <option name="RIGHT_MARGIN" value="100"/>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> <option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
<option name="JD_P_AT_EMPTY_LINES" value="false" /> <option name="JD_P_AT_EMPTY_LINES" value="false"/>
<option name="JD_KEEP_EMPTY_PARAMETER" value="false" /> <option name="JD_KEEP_EMPTY_PARAMETER" value="false"/>
<option name="JD_KEEP_EMPTY_EXCEPTION" value="false" /> <option name="JD_KEEP_EMPTY_EXCEPTION" value="false"/>
<option name="JD_KEEP_EMPTY_RETURN" value="false" /> <option name="JD_KEEP_EMPTY_RETURN" value="false"/>
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" /> <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" /> <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="0" /> <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="0"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false" /> <option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="CALL_PARAMETERS_WRAP" value="1" /> <option name="CALL_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_PARAMETERS_WRAP" value="1" /> <option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1"/>
<option name="THROWS_KEYWORD_WRAP" value="1" /> <option name="THROWS_KEYWORD_WRAP" value="1"/>
<option name="METHOD_CALL_CHAIN_WRAP" value="1" /> <option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
<option name="BINARY_OPERATION_WRAP" value="1" /> <option name="BINARY_OPERATION_WRAP" value="1"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="TERNARY_OPERATION_WRAP" value="1" /> <option name="TERNARY_OPERATION_WRAP" value="1"/>
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
<option name="FOR_STATEMENT_WRAP" value="1" /> <option name="FOR_STATEMENT_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_WRAP" value="1" /> <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
<option name="WRAP_COMMENTS" value="true" /> <option name="WRAP_COMMENTS" value="true"/>
<option name="IF_BRACE_FORCE" value="3" /> <option name="IF_BRACE_FORCE" value="3"/>
<option name="DOWHILE_BRACE_FORCE" value="3" /> <option name="DOWHILE_BRACE_FORCE" value="3"/>
<option name="WHILE_BRACE_FORCE" value="3" /> <option name="WHILE_BRACE_FORCE" value="3"/>
<option name="FOR_BRACE_FORCE" value="3" /> <option name="FOR_BRACE_FORCE" value="3"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" /> <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<AndroidXmlCodeStyleSettings> <AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" /> <option name="USE_CUSTOM_SETTINGS" value="true"/>
<option name="LAYOUT_SETTINGS"> <option name="LAYOUT_SETTINGS">
<value> <value>
<option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false" /> <option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false"/>
</value> </value>
</option> </option>
</AndroidXmlCodeStyleSettings> </AndroidXmlCodeStyleSettings>
<JSCodeStyleSettings> <JSCodeStyleSettings>
<option name="INDENT_CHAINED_CALLS" value="false" /> <option name="INDENT_CHAINED_CALLS" value="false"/>
</JSCodeStyleSettings> </JSCodeStyleSettings>
<Python> <Python>
<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true" /> <option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true"/>
</Python> </Python>
<TypeScriptCodeStyleSettings> <TypeScriptCodeStyleSettings>
<option name="INDENT_CHAINED_CALLS" value="false" /> <option name="INDENT_CHAINED_CALLS" value="false"/>
</TypeScriptCodeStyleSettings> </TypeScriptCodeStyleSettings>
<XML> <XML>
<option name="XML_ALIGN_ATTRIBUTES" value="false" /> <option name="XML_ALIGN_ATTRIBUTES" value="false"/>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
</XML> </XML>
<codeStyleSettings language="CSS"> <codeStyleSettings language="CSS">
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4"> <codeStyleSettings language="ECMA Script Level 4">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false" /> <option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="CALL_PARAMETERS_WRAP" value="1" /> <option name="CALL_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_PARAMETERS_WRAP" value="1" /> <option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1"/>
<option name="BINARY_OPERATION_WRAP" value="1" /> <option name="BINARY_OPERATION_WRAP" value="1"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="TERNARY_OPERATION_WRAP" value="1" /> <option name="TERNARY_OPERATION_WRAP" value="1"/>
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
<option name="FOR_STATEMENT_WRAP" value="1" /> <option name="FOR_STATEMENT_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_WRAP" value="1" /> <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
<option name="IF_BRACE_FORCE" value="3" /> <option name="IF_BRACE_FORCE" value="3"/>
<option name="DOWHILE_BRACE_FORCE" value="3" /> <option name="DOWHILE_BRACE_FORCE" value="3"/>
<option name="WHILE_BRACE_FORCE" value="3" /> <option name="WHILE_BRACE_FORCE" value="3"/>
<option name="FOR_BRACE_FORCE" value="3" /> <option name="FOR_BRACE_FORCE" value="3"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true" /> <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="HTML"> <codeStyleSettings language="HTML">
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JAVA"> <codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" /> <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_RESOURCES" value="false" /> <option name="ALIGN_MULTILINE_RESOURCES" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false" /> <option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="CALL_PARAMETERS_WRAP" value="1" /> <option name="CALL_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_PARAMETERS_WRAP" value="1" /> <option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1"/>
<option name="THROWS_KEYWORD_WRAP" value="1" /> <option name="THROWS_KEYWORD_WRAP" value="1"/>
<option name="METHOD_CALL_CHAIN_WRAP" value="1" /> <option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
<option name="BINARY_OPERATION_WRAP" value="1" /> <option name="BINARY_OPERATION_WRAP" value="1"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="TERNARY_OPERATION_WRAP" value="1" /> <option name="TERNARY_OPERATION_WRAP" value="1"/>
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
<option name="FOR_STATEMENT_WRAP" value="1" /> <option name="FOR_STATEMENT_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_WRAP" value="1" /> <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
<option name="WRAP_COMMENTS" value="true" /> <option name="WRAP_COMMENTS" value="true"/>
<option name="IF_BRACE_FORCE" value="3" /> <option name="IF_BRACE_FORCE" value="3"/>
<option name="DOWHILE_BRACE_FORCE" value="3" /> <option name="DOWHILE_BRACE_FORCE" value="3"/>
<option name="WHILE_BRACE_FORCE" value="3" /> <option name="WHILE_BRACE_FORCE" value="3"/>
<option name="FOR_BRACE_FORCE" value="3" /> <option name="FOR_BRACE_FORCE" value="3"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true" /> <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JSON"> <codeStyleSettings language="JSON">
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JavaScript"> <codeStyleSettings language="JavaScript">
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false" /> <option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="CALL_PARAMETERS_WRAP" value="1" /> <option name="CALL_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_PARAMETERS_WRAP" value="1" /> <option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="BINARY_OPERATION_WRAP" value="1" /> <option name="BINARY_OPERATION_WRAP" value="1"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="TERNARY_OPERATION_WRAP" value="1" /> <option name="TERNARY_OPERATION_WRAP" value="1"/>
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
<option name="FOR_STATEMENT_WRAP" value="1" /> <option name="FOR_STATEMENT_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_WRAP" value="1" /> <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
<option name="IF_BRACE_FORCE" value="3" /> <option name="IF_BRACE_FORCE" value="3"/>
<option name="DOWHILE_BRACE_FORCE" value="3" /> <option name="DOWHILE_BRACE_FORCE" value="3"/>
<option name="WHILE_BRACE_FORCE" value="3" /> <option name="WHILE_BRACE_FORCE" value="3"/>
<option name="FOR_BRACE_FORCE" value="3" /> <option name="FOR_BRACE_FORCE" value="3"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true" /> <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="PROTO"> <codeStyleSettings language="PROTO">
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="2" /> <option name="CONTINUATION_INDENT_SIZE" value="2"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="protobuf"> <codeStyleSettings language="protobuf">
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="2" /> <option name="CONTINUATION_INDENT_SIZE" value="2"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="Python"> <codeStyleSettings language="Python">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true" /> <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="SASS"> <codeStyleSettings language="SASS">
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="SCSS"> <codeStyleSettings language="SCSS">
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="TypeScript"> <codeStyleSettings language="TypeScript">
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="XML"> <codeStyleSettings language="XML">
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="2" /> <option name="CONTINUATION_INDENT_SIZE" value="2"/>
<option name="TAB_SIZE" value="2" /> <option name="TAB_SIZE" value="2"/>
</indentOptions> </indentOptions>
<arrangement> <arrangement>
<rules> <rules>
@@ -226,7 +226,7 @@
<match> <match>
<AND> <AND>
<NAME>xmlns:android</NAME> <NAME>xmlns:android</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -237,7 +237,7 @@
<match> <match>
<AND> <AND>
<NAME>xmlns:.*</NAME> <NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -249,7 +249,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:id</NAME> <NAME>.*:id</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -260,7 +260,7 @@
<match> <match>
<AND> <AND>
<NAME>style</NAME> <NAME>style</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -271,7 +271,7 @@
<match> <match>
<AND> <AND>
<NAME>.*</NAME> <NAME>.*</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -283,7 +283,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:.*Style</NAME> <NAME>.*:.*Style</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -295,7 +295,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_width</NAME> <NAME>.*:layout_width</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -306,7 +306,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_height</NAME> <NAME>.*:layout_height</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -317,7 +317,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_weight</NAME> <NAME>.*:layout_weight</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -328,7 +328,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_margin</NAME> <NAME>.*:layout_margin</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -339,7 +339,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginTop</NAME> <NAME>.*:layout_marginTop</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -350,7 +350,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginBottom</NAME> <NAME>.*:layout_marginBottom</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -361,7 +361,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginStart</NAME> <NAME>.*:layout_marginStart</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -372,7 +372,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginEnd</NAME> <NAME>.*:layout_marginEnd</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -383,7 +383,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginLeft</NAME> <NAME>.*:layout_marginLeft</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -394,7 +394,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_marginRight</NAME> <NAME>.*:layout_marginRight</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -405,7 +405,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:layout_.*</NAME> <NAME>.*:layout_.*</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -417,7 +417,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:padding</NAME> <NAME>.*:padding</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -428,7 +428,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingTop</NAME> <NAME>.*:paddingTop</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -439,7 +439,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingBottom</NAME> <NAME>.*:paddingBottom</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -450,7 +450,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingStart</NAME> <NAME>.*:paddingStart</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -461,7 +461,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingEnd</NAME> <NAME>.*:paddingEnd</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -472,7 +472,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingLeft</NAME> <NAME>.*:paddingLeft</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -483,7 +483,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:paddingRight</NAME> <NAME>.*:paddingRight</NAME>
<XML_ATTRIBUTE /> <XML_ATTRIBUTE/>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@@ -537,62 +537,62 @@
</arrangement> </arrangement>
</codeStyleSettings> </codeStyleSettings>
<Objective-C> <Objective-C>
<option name="INDENT_NAMESPACE_MEMBERS" value="0" /> <option name="INDENT_NAMESPACE_MEMBERS" value="0"/>
<option name="INDENT_C_STRUCT_MEMBERS" value="2" /> <option name="INDENT_C_STRUCT_MEMBERS" value="2"/>
<option name="INDENT_CLASS_MEMBERS" value="2" /> <option name="INDENT_CLASS_MEMBERS" value="2"/>
<option name="INDENT_VISIBILITY_KEYWORDS" value="1" /> <option name="INDENT_VISIBILITY_KEYWORDS" value="1"/>
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" /> <option name="INDENT_INSIDE_CODE_BLOCK" value="2"/>
<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" /> <option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true"/>
<option name="FUNCTION_PARAMETERS_WRAP" value="5" /> <option name="FUNCTION_PARAMETERS_WRAP" value="5"/>
<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" /> <option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5"/>
<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" /> <option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5"/>
<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" /> <option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true"/>
<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" /> <option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false"/>
<option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false" /> <option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false"/>
</Objective-C> </Objective-C>
<Objective-C-extensions> <Objective-C-extensions>
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" /> <option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK"/>
<option name="RELEASE_STYLE" value="IVAR" /> <option name="RELEASE_STYLE" value="IVAR"/>
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" /> <option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE"/>
<file> <file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function"/>
</file> </file>
<class> <class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod"/>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod"/>
</class> </class>
<extensions> <extensions>
<pair source="cc" header="h" /> <pair source="cc" header="h"/>
<pair source="c" header="h" /> <pair source="c" header="h"/>
</extensions> </extensions>
</Objective-C-extensions> </Objective-C-extensions>
<codeStyleSettings language="ObjectiveC"> <codeStyleSettings language="ObjectiveC">
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="BLANK_LINES_BEFORE_IMPORTS" value="0" /> <option name="BLANK_LINES_BEFORE_IMPORTS" value="0"/>
<option name="BLANK_LINES_AFTER_IMPORTS" value="0" /> <option name="BLANK_LINES_AFTER_IMPORTS" value="0"/>
<option name="BLANK_LINES_AROUND_CLASS" value="0" /> <option name="BLANK_LINES_AROUND_CLASS" value="0"/>
<option name="BLANK_LINES_AROUND_METHOD" value="0" /> <option name="BLANK_LINES_AROUND_METHOD" value="0"/>
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" /> <option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0"/>
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" /> <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="FOR_STATEMENT_WRAP" value="1" /> <option name="FOR_STATEMENT_WRAP" value="1"/>
<option name="ASSIGNMENT_WRAP" value="1" /> <option name="ASSIGNMENT_WRAP" value="1"/>
<indentOptions> <indentOptions>
<option name="INDENT_SIZE" value="2" /> <option name="INDENT_SIZE" value="2"/>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>

View File

@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
@@ -20,16 +21,16 @@
<artifactId>cxf-rt-transports-http</artifactId> <artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version> <version>${cxf.version}</version>
</dependency> </dependency>
<!-- <dependency> --> <!-- <dependency> -->
<!-- <groupId>org.apache.cxf.services.ws-discovery</groupId> --> <!-- <groupId>org.apache.cxf.services.ws-discovery</groupId> -->
<!-- <artifactId>cxf-services-ws-discovery-api</artifactId> --> <!-- <artifactId>cxf-services-ws-discovery-api</artifactId> -->
<!-- <version>${cxf.version}</version> --> <!-- <version>${cxf.version}</version> -->
<!-- </dependency> --> <!-- </dependency> -->
<!-- <dependency> --> <!-- <dependency> -->
<!-- <groupId>org.apache.cxf.services.ws-discovery</groupId> --> <!-- <groupId>org.apache.cxf.services.ws-discovery</groupId> -->
<!-- <artifactId>cxf-services-ws-discovery-service</artifactId> --> <!-- <artifactId>cxf-services-ws-discovery-service</artifactId> -->
<!-- <version>${cxf.version}</version> --> <!-- <version>${cxf.version}</version> -->
<!-- </dependency> --> <!-- </dependency> -->
<dependency> <dependency>
<groupId>org.onvif</groupId> <groupId>org.onvif</groupId>
@@ -63,13 +64,13 @@
<!-- For discovery using cxf --> <!-- For discovery using cxf -->
<!-- https://mvnrepository.com/artifact/org.apache.cxf.services.ws-discovery/cxf-services-ws-discovery-api --> <!-- https://mvnrepository.com/artifact/org.apache.cxf.services.ws-discovery/cxf-services-ws-discovery-api -->
<!-- <!--
<dependency> <dependency>
<groupId>org.apache.cxf.services.ws-discovery</groupId> <groupId>org.apache.cxf.services.ws-discovery</groupId>
<artifactId>cxf-services-ws-discovery-api</artifactId> <artifactId>cxf-services-ws-discovery-api</artifactId>
<version>${cxf.version}</version> <version>${cxf.version}</version>
</dependency> </dependency>
--> -->
<!-- Java 9+ javax dependencies start --> <!-- Java 9+ javax dependencies start -->
<dependency> <dependency>
@@ -109,10 +110,9 @@
</dependency> </dependency>
</dependencies> </dependencies>
<!-- <!--
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@@ -125,5 +125,5 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
--> -->
</project> </project>

View File

@@ -1,25 +1,28 @@
package de.onvif.soap; package de.onvif.soap;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.HTTPConduit;
import javax.net.ssl.*;
import javax.xml.ws.BindingProvider;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.BindingProvider;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.HTTPConduit;
public class NaiveSSLHelper { public class NaiveSSLHelper {
public static void makeWebServiceClientTrustEveryone( public static void makeWebServiceClientTrustEveryone(Object webServicePort) {
Object webServicePort) {
if (webServicePort instanceof BindingProvider) { if (webServicePort instanceof BindingProvider) {
BindingProvider bp = (BindingProvider) webServicePort; BindingProvider bp = (BindingProvider) webServicePort;
Map requestContext = bp.getRequestContext(); Map requestContext = bp.getRequestContext();
requestContext.put(JAXWS_SSL_SOCKET_FACTORY, getTrustingSSLSocketFactory()); requestContext.put(JAXWS_SSL_SOCKET_FACTORY, getTrustingSSLSocketFactory());
requestContext.put(JAXWS_HOSTNAME_VERIFIER, requestContext.put(JAXWS_HOSTNAME_VERIFIER, new NaiveHostnameVerifier());
new NaiveHostnameVerifier());
} else { } else {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Web service port " "Web service port "
@@ -34,14 +37,11 @@ public class NaiveSSLHelper {
} }
private static SSLSocketFactory createSSLSocketFactory() { private static SSLSocketFactory createSSLSocketFactory() {
TrustManager[] trustManagers = new TrustManager[] { TrustManager[] trustManagers = new TrustManager[] {new NaiveTrustManager()};
new NaiveTrustManager()
};
SSLContext sslContext; SSLContext sslContext;
try { try {
sslContext = SSLContext.getInstance("TLS"); sslContext = SSLContext.getInstance("TLS");
sslContext.init(new KeyManager[0], trustManagers, sslContext.init(new KeyManager[0], trustManagers, new SecureRandom());
new SecureRandom());
return sslContext.getSocketFactory(); return sslContext.getSocketFactory();
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
return null; return null;
@@ -49,9 +49,7 @@ public class NaiveSSLHelper {
} }
public static void makeCxfWebServiceClientTrustEveryone(HTTPConduit http) { public static void makeCxfWebServiceClientTrustEveryone(HTTPConduit http) {
TrustManager[] trustManagers = new TrustManager[]{ TrustManager[] trustManagers = new TrustManager[] {new NaiveTrustManager()};
new NaiveTrustManager()
};
TLSClientParameters tlsParams = new TLSClientParameters(); TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("TLS"); tlsParams.setSecureSocketProtocol("TLS");
tlsParams.setKeyManagers(new KeyManager[0]); tlsParams.setKeyManagers(new KeyManager[0]);
@@ -64,27 +62,22 @@ public class NaiveSSLHelper {
SSLSocketFactory INSTANCE = createSSLSocketFactory(); SSLSocketFactory INSTANCE = createSSLSocketFactory();
} }
private static class NaiveHostnameVerifier implements private static class NaiveHostnameVerifier implements HostnameVerifier {
HostnameVerifier {
@Override @Override
public boolean verify(String hostName, public boolean verify(String hostName, SSLSession session) {
SSLSession session) {
return true; return true;
} }
} }
private static class NaiveTrustManager implements private static class NaiveTrustManager implements X509TrustManager {
X509TrustManager {
@Override @Override
public void checkClientTrusted(X509Certificate[] certs, public void checkClientTrusted(X509Certificate[] certs, String authType)
String authType) throws CertificateException { throws CertificateException {}
}
@Override @Override
public void checkServerTrusted(X509Certificate[] certs, public void checkServerTrusted(X509Certificate[] certs, String authType)
String authType) throws CertificateException { throws CertificateException {}
}
@Override @Override
public X509Certificate[] getAcceptedIssuers() { public X509Certificate[] getAcceptedIssuers() {

View File

@@ -62,16 +62,27 @@ public class OnvifDevice {
private static boolean verbose = false; // enable/disable logging of SOAP messages private static boolean verbose = false; // enable/disable logging of SOAP messages
final SimpleSecurityHandler securityHandler; final SimpleSecurityHandler securityHandler;
private static URL cleanURL(URL u) throws ConnectException {
if (u == null) throw new ConnectException("null url not allowed");
String f = u.getFile();
if (!f.isEmpty()) {
String out = u.toString().replace(f, "");
try {
return new URL(out);
} catch (MalformedURLException e) {
throw new ConnectException("MalformedURLException " + u);
}
}
return u;
}
/* /*
* @param url is http://host or http://host:port or https://host or https://host:port * @param url is http://host or http://host:port or https://host or https://host:port
* @param user Username you need to login, or "" for none * @param user Username you need to login, or "" for none
* @param password User's password to login, or "" for none * @param password User's password to login, or "" for none
*/ */
public OnvifDevice(URL url, String user, String password) public OnvifDevice(URL url, String user, String password) throws ConnectException, SOAPException {
throws ConnectException, SOAPException, MalformedURLException { this.url = cleanURL(url);
this.url = url;
String f = url.getFile();
if (!f.isEmpty()) throw new MalformedURLException("Expected empty file in URL, not:" + f);
securityHandler = securityHandler =
!user.isEmpty() && !password.isEmpty() ? new SimpleSecurityHandler(user, password) : null; !user.isEmpty() && !password.isEmpty() ? new SimpleSecurityHandler(user, password) : null;
init(); init();
@@ -289,8 +300,8 @@ public class OnvifDevice {
return getSnapshotUri(0); return getSnapshotUri(0);
} }
public String getRTSPUri() { public String getStreamUri() {
return getRTSPUri(0); return getStreamUri(0);
} }
// Get snapshot uri for profile with index // Get snapshot uri for profile with index
@@ -300,12 +311,12 @@ public class OnvifDevice {
return ""; return "";
} }
public String getRTSPUri(int index) { public String getStreamUri(int index) {
return getRTSPUri(media.getProfiles().get(index).getToken()); return getStreamUri(media.getProfiles().get(index).getToken());
} }
// returns rtsp://host[:port]/path_for_rtsp // returns rtsp://host[:port]/path_for_rtsp
public String getRTSPUri(String profileToken) { public String getStreamUri(String profileToken) {
StreamSetup streamSetup = new StreamSetup(); StreamSetup streamSetup = new StreamSetup();
Transport t = new Transport(); Transport t = new Transport();
t.setProtocol(TransportProtocol.RTSP); t.setProtocol(TransportProtocol.RTSP);

View File

@@ -37,7 +37,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.MessageDigestAlgorithms; import org.apache.commons.codec.digest.MessageDigestAlgorithms;
/* /*
Utility class to add user/password onvif credentials to SOAP communications Utility class to add user/password onvif credentials to SOAP communications
*/ */
public class SimpleSecurityHandler implements SOAPHandler<SOAPMessageContext> { public class SimpleSecurityHandler implements SOAPHandler<SOAPMessageContext> {
private final String username; private final String username;

View File

@@ -1,6 +1,5 @@
# Root logger option # Root logger option
log4j.rootLogger=INFO, stdout log4j.rootLogger=INFO, stdout
# Direct log messages to stdout # Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out log4j.appender.stdout.Target=System.out

View File

@@ -1,13 +0,0 @@
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:tns="http://schemas.xmlsoap.org/ws/2005/04/discovery">
<soap:Header>
<wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action>
<wsa:MessageID>urn:uuid:c032cfdd-c3ca-49dc-820e-ee6696ad63e2</wsa:MessageID>
<wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To>
</soap:Header>
<soap:Body>
<tns:Probe />
</soap:Body>
</soap:Envelope>

View File

@@ -6,16 +6,17 @@ import java.io.StringWriter;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.logging.Logger; import org.slf4j.Logger;
import org.apache.cxf.common.logging.LogUtils; import org.slf4j.LoggerFactory;
/** /**
* Class calls OnvifDiscovery and for each device URL found, calls TestDevice * Class calls OnvifDiscovery and for each device URL found, calls TestDevice This assumes all onvif
* This assumes all onvif devices on your network use the same username and password. * devices on your network use the same username and password.
*
* @author Brad Lowe * @author Brad Lowe
*/ */
public class DiscoverAndTest { public class DiscoverAndTest {
private static final Logger LOG = LogUtils.getL7dLogger(TestDevice.class); private static final Logger LOG = LoggerFactory.getLogger(TestDevice.class);
public static String discoverAndTest(String user, String password) { public static String discoverAndTest(String user, String password) {
String sep = "\n"; String sep = "\n";
@@ -38,10 +39,10 @@ public class DiscoverAndTest {
results.add(u.toString() + ":" + result); results.add(u.toString() + ":" + result);
} catch (Throwable e) { } catch (Throwable e) {
bad++; bad++;
LOG.severe("error:" + u + " " + e.toString()); LOG.error("error:" + u, e);
// This is a bit of a hack. When a camera is password protected (it should be!) // This is a bit of a hack. When a camera is password protected (it should be!)
// and the password is not provided or wrong, a "Unable to Send Message" exception // and the password is not provided or wrong, a "Unable to Send Message" exception
// is thrown. This is not clear-- buried in the stack track is the real cause. // may be thrown. This is not clear-- buried in the stack track is the real cause.
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw); PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw); e.printStackTrace(pw);
@@ -58,8 +59,16 @@ public class DiscoverAndTest {
public static void main(String[] args) { public static void main(String[] args) {
// get user and password.. we will ignore device host // get user and password.. we will ignore device host
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args); String user = "";
if (creds.getPassword().isEmpty()) LOG.info("Warning: No password for discover and test..."); String password = "";
LOG.info(discoverAndTest(creds.getUser(), creds.getPassword())); if (args.length > 0) user = args[0];
if (args.length > 1) password = args[1];
if (password.isEmpty()) {
LOG.info(
"Warning: No password for discover and test... run with common user password as arguments");
}
// OnvifDevice.setVerbose(true);
LOG.info(discoverAndTest(user, password));
} }
} }

View File

@@ -1,16 +1,13 @@
package org.onvif.client; package org.onvif.client;
import de.onvif.discovery.OnvifDiscovery; import de.onvif.discovery.OnvifDiscovery;
import org.apache.cxf.common.logging.LogUtils;
import java.net.URL; import java.net.URL;
import java.util.Collection; import java.util.Collection;
import java.util.logging.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DiscoveryTest { public class DiscoveryTest {
private static final Logger LOG = LogUtils.getL7dLogger(DiscoveryTest.class); private static final Logger LOG = LoggerFactory.getLogger(DiscoveryTest.class);
public static void main(String[] args) { public static void main(String[] args) {
Collection<URL> urls = OnvifDiscovery.discoverOnvifURLs(); Collection<URL> urls = OnvifDiscovery.discoverOnvifURLs();
@@ -19,4 +16,3 @@ public class DiscoveryTest {
} }
} }
} }

View File

@@ -1,61 +1,59 @@
package org.onvif.client; package org.onvif.client;
import org.apache.cxf.common.logging.LogUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Scanner; import java.util.Scanner;
import java.util.logging.Level; import org.slf4j.Logger;
import java.util.logging.Logger; import org.slf4j.LoggerFactory;
public class GetTestDevice { public class GetTestDevice {
static String PROPERTY_NAME="ONVIF_HOST"; static String PROPERTY_NAME = "ONVIF_HOST";
private static final Logger LOG = LogUtils.getL7dLogger(GetTestDevice.class); private static final Logger LOG = LoggerFactory.getLogger(GetTestDevice.class);
// Get a camera host, user name, and password for tests. // Get a camera host, user name, and password for tests.
// Add an environment variable or java Property called "TEST_CAM" and set to host,user,password,profile // Add an environment variable or java Property called "TEST_CAM" and set to
// host,user,password,profile
// or modify resource/onvif.properties // or modify resource/onvif.properties
public static OnvifCredentials getOnvifCredentials(String args[]) { public static OnvifCredentials getOnvifCredentials(String[] args) {
OnvifCredentials creds = getFromArgs(args); OnvifCredentials creds = getFromArgs(args);
if (creds!=null) return creds; if (creds != null) return creds;
creds = getFromProperties(); creds = getFromProperties();
if (creds!=null) return creds; if (creds != null) return creds;
try { try {
creds = getFirstFromResource("/onvif.properties"); creds = getFirstFromResource("/onvif.properties");
if (creds != null) return creds; if (creds != null) return creds;
}catch(IOException ioe) } catch (IOException ioe) {
{ LOG.error("Error", ioe);
LOG.log(Level.WARNING, "Error", ioe);
} }
try { try {
creds = getFromStandardInput(); creds = getFromStandardInput();
if (creds != null) return creds; if (creds != null) return creds;
}catch(IOException ioe) } catch (IOException ioe) {
{ LOG.error("Error", ioe);
LOG.log(Level.WARNING, "Error", ioe);
} }
LOG.info("Unable to get default test onvif credentials"); LOG.info("Unable to get default test onvif credentials");
return new OnvifCredentials("","","",""); return new OnvifCredentials("", "", "", "");
} }
// arguments to any test app can be host user password profilename // arguments to any test app can be host user password profilename
// if no arguments passed, returns null. // if no arguments passed, returns null.
// All arguments optional. // All arguments optional.
public static OnvifCredentials getFromArgs(String[] args) { public static OnvifCredentials getFromArgs(String[] args) {
if (args==null||args.length==0) return null; if (args == null || args.length == 0) return null;
String host="",user="",password="",profile=""; String host = "", user = "", password = "", profile = "";
host = args[0]; host = args[0];
if (args.length > 1) user = args[1]; if (args.length > 1) user = args[1];
if (args.length > 2) password = args[2]; if (args.length > 2) password = args[2];
if (args.length > 3) profile = args[3]; if (args.length > 3) profile = args[3];
return new OnvifCredentials(host,user,password,profile); return new OnvifCredentials(host, user, password, profile);
} }
public static OnvifCredentials getFromProperties() { public static OnvifCredentials getFromProperties() {
@@ -72,7 +70,7 @@ public class GetTestDevice {
private static OnvifCredentials getFromStandardInput() throws IOException { private static OnvifCredentials getFromStandardInput() throws IOException {
System.out.println("Getting camera credentials from standard input"); System.out.println("Getting camera credentials from standard input");
InputStreamReader inputStream = new InputStreamReader(System.in, "utf-8"); InputStreamReader inputStream = new InputStreamReader(System.in, StandardCharsets.UTF_8);
BufferedReader keyboardInput = new BufferedReader(inputStream); BufferedReader keyboardInput = new BufferedReader(inputStream);
System.out.println("Please enter camera IP (with port if not 80):"); System.out.println("Please enter camera IP (with port if not 80):");
String cameraAddress = keyboardInput.readLine(); String cameraAddress = keyboardInput.readLine();
@@ -85,15 +83,16 @@ public class GetTestDevice {
OnvifCredentials creds = new OnvifCredentials(cameraAddress, user, password, profile); OnvifCredentials creds = new OnvifCredentials(cameraAddress, user, password, profile);
return creds; return creds;
} }
private static OnvifCredentials getFirstFromResource(String resource) throws IOException { private static OnvifCredentials getFirstFromResource(String resource) throws IOException {
InputStream res = GetTestDevice.class.getResourceAsStream(resource); InputStream res = GetTestDevice.class.getResourceAsStream(resource);
if (res != null) { if (res != null) {
Scanner s = new Scanner(res, "UTF-8").useDelimiter("\\A"); Scanner s = new Scanner(res, StandardCharsets.UTF_8).useDelimiter("\\A");
while (s.hasNextLine()) { while (s.hasNextLine()) {
String line = s.nextLine(); String line = s.nextLine();
if (!line.isEmpty() && !line.startsWith("#")) if (!line.isEmpty() && !line.startsWith("#"))
return parse(line.substring(line.indexOf("=")+1)); return parse(line.substring(line.indexOf("=") + 1));
} }
} }
return null; return null;
@@ -104,7 +103,7 @@ public class GetTestDevice {
String host = "", user = "", password = "", profile = ""; String host = "", user = "", password = "", profile = "";
if (i != null) { if (i != null) {
if (i.contains(",")) { if (i.contains(",")) {
String sp[] = i.split(","); String[] sp = i.split(",");
if (sp.length > 0) host = sp[0]; if (sp.length > 0) host = sp[0];
if (sp.length > 1) user = sp[1]; if (sp.length > 1) user = sp[1];
if (sp.length > 2) password = sp[2]; if (sp.length > 2) password = sp[2];
@@ -114,6 +113,4 @@ public class GetTestDevice {
} }
return new OnvifCredentials(host, user, password, profile); return new OnvifCredentials(host, user, password, profile);
} }
} }

View File

@@ -1,21 +1,21 @@
package org.onvif.client; package org.onvif.client;
import de.onvif.soap.OnvifDevice; import de.onvif.soap.OnvifDevice;
import org.onvif.ver10.schema.Profile;
import javax.xml.soap.SOAPException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.List; import java.util.List;
import javax.xml.soap.SOAPException;
import org.onvif.ver10.schema.Profile;
public class ReadCommandsFromStdInput { public class ReadCommandsFromStdInput {
private static final String INFO = "Commands:\n \n url: Get snapshort URL.\n info: Get information about each valid command.\n profiles: Get all profiles.\n inspect: Get device details.\n exit: Exit this application."; private static final String INFO =
"Commands:\n \n url: Get snapshort URL.\n info: Get information about each valid command.\n profiles: Get all profiles.\n inspect: Get device details.\n exit: Exit this application.";
public static void main(String args[]) { public static void main(String[] args) {
InputStreamReader inputStream = new InputStreamReader(System.in); InputStreamReader inputStream = new InputStreamReader(System.in);
BufferedReader keyboardInput = new BufferedReader(inputStream); BufferedReader keyboardInput = new BufferedReader(inputStream);
String input, cameraAddress, user, password; String input, cameraAddress, user, password;
@@ -27,7 +27,8 @@ public class ReadCommandsFromStdInput {
user = keyboardInput.readLine(); user = keyboardInput.readLine();
System.out.println("Please enter camera password:"); System.out.println("Please enter camera password:");
password = keyboardInput.readLine(); password = keyboardInput.readLine();
if (cameraAddress==null||user==null||password==null) throw new IOException("No input"); if (cameraAddress == null || user == null || password == null)
throw new IOException("No input");
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
return; return;
@@ -49,12 +50,17 @@ public class ReadCommandsFromStdInput {
System.out.println(); System.out.println();
System.out.println("Enter a command (type \"info\" to get commands):"); System.out.println("Enter a command (type \"info\" to get commands):");
input = keyboardInput.readLine(); input = keyboardInput.readLine();
if (input==null) break; if (input == null) break;
switch (input) { switch (input) {
case "url": { case "url":
{
List<Profile> profiles = cam.getMedia().getProfiles(); List<Profile> profiles = cam.getMedia().getProfiles();
for (Profile p : profiles) { for (Profile p : profiles) {
System.out.println("URL from Profile \'" + p.getName() + "\': " + cam.getMedia().getSnapshotUri(p.getToken())); System.out.println(
"URL from Profile \'"
+ p.getName()
+ "\': "
+ cam.getMedia().getSnapshotUri(p.getToken()));
} }
break; break;
} }

View File

@@ -1,24 +1,13 @@
package org.onvif.client; package org.onvif.client;
import de.onvif.soap.OnvifDevice; import de.onvif.soap.OnvifDevice;
import de.onvif.utils.OnvifUtils;
import org.apache.commons.io.FileUtils;
import org.onvif.ver10.media.wsdl.Media;
import org.onvif.ver10.schema.*;
import org.onvif.ver20.ptz.wsdl.PTZ;
import javax.xml.soap.SOAPException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.lang.Object;
import java.net.ConnectException;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties; import java.util.Properties;
import org.apache.commons.io.FileUtils;
public class SimpleTest { public class SimpleTest {
@@ -26,7 +15,6 @@ public class SimpleTest {
// screenshot // screenshot
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
final Map<String, OnvifDevice> onvifCameras = new HashMap<>(); final Map<String, OnvifDevice> onvifCameras = new HashMap<>();
final Map<String, OnvifCredentials> credentialsMap = new HashMap<>(); final Map<String, OnvifCredentials> credentialsMap = new HashMap<>();
final String propFileRelativePath = "src/test/resources/onvif.properties"; final String propFileRelativePath = "src/test/resources/onvif.properties";
@@ -35,15 +23,15 @@ public class SimpleTest {
if (!f.exists()) throw new Exception("fnf: " + f.getAbsolutePath()); if (!f.exists()) throw new Exception("fnf: " + f.getAbsolutePath());
config.load(new FileInputStream(f)); config.load(new FileInputStream(f));
for (Object k:config.keySet()) for (Object k : config.keySet()) {
{
String line = config.get(k.toString()).toString(); String line = config.get(k.toString()).toString();
OnvifCredentials credentials = GetTestDevice.parse(line); OnvifCredentials credentials = GetTestDevice.parse(line);
if (credentials!=null) if (credentials != null) {
{
try { try {
System.out.println("Connect to camera, please wait ..."); System.out.println("Connect to camera, please wait ...");
OnvifDevice cam = new OnvifDevice(credentials.getHost(), credentials.getUser(), credentials.getPassword()); OnvifDevice cam =
new OnvifDevice(
credentials.getHost(), credentials.getUser(), credentials.getPassword());
System.out.printf("Connected to device %s (%s)%n", cam.getDeviceInfo(), k.toString()); System.out.printf("Connected to device %s (%s)%n", cam.getDeviceInfo(), k.toString());
System.out.println(TestDevice.inspect(cam)); System.out.println(TestDevice.inspect(cam));
@@ -54,19 +42,15 @@ public class SimpleTest {
// Note: This will likely fail if the camera/device is password protected. // Note: This will likely fail if the camera/device is password protected.
// embedding the user:password@ into the URL will not work with FileUtils.copyURLToFile // embedding the user:password@ into the URL will not work with FileUtils.copyURLToFile
FileUtils.copyURLToFile(new URL(snapshotUri), tempFile); FileUtils.copyURLToFile(new URL(snapshotUri), tempFile);
System.out.println("snapshot: " + tempFile.getAbsolutePath() + " length:" + tempFile.length()); System.out.println(
"snapshot: " + tempFile.getAbsolutePath() + " length:" + tempFile.length());
} }
} catch (Throwable th) {
}catch(Throwable th) System.err.println("Error on device: " + k);
{
System.err.println("Error on device: "+k);
th.printStackTrace(); th.printStackTrace();
} }
} }
} }
} }
} }

View File

@@ -3,35 +3,38 @@ package org.onvif.client;
import de.onvif.beans.DeviceInfo; import de.onvif.beans.DeviceInfo;
import de.onvif.soap.OnvifDevice; import de.onvif.soap.OnvifDevice;
import de.onvif.utils.OnvifUtils; import de.onvif.utils.OnvifUtils;
import org.apache.cxf.common.logging.LogUtils; import java.io.IOException;
import java.net.URL;
import java.util.List;
import javax.xml.soap.SOAPException;
import org.onvif.ver10.device.wsdl.DeviceServiceCapabilities; import org.onvif.ver10.device.wsdl.DeviceServiceCapabilities;
import org.onvif.ver10.events.wsdl.EventPortType; import org.onvif.ver10.events.wsdl.EventPortType;
import org.onvif.ver10.events.wsdl.GetEventProperties; import org.onvif.ver10.events.wsdl.GetEventProperties;
import org.onvif.ver10.events.wsdl.GetEventPropertiesResponse; import org.onvif.ver10.events.wsdl.GetEventPropertiesResponse;
import org.onvif.ver10.media.wsdl.Media; import org.onvif.ver10.media.wsdl.Media;
import org.onvif.ver10.schema.*; import org.onvif.ver10.schema.AudioSource;
import org.onvif.ver10.schema.PTZPreset;
import org.onvif.ver10.schema.PTZStatus;
import org.onvif.ver10.schema.Profile;
import org.onvif.ver10.schema.VideoSource;
import org.onvif.ver20.imaging.wsdl.ImagingPort; import org.onvif.ver20.imaging.wsdl.ImagingPort;
import org.onvif.ver20.ptz.wsdl.Capabilities; import org.onvif.ver20.ptz.wsdl.Capabilities;
import org.onvif.ver20.ptz.wsdl.PTZ; import org.onvif.ver20.ptz.wsdl.PTZ;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import javax.xml.soap.SOAPException; /** @author Brad Lowe */
import java.io.IOException;
import java.lang.Object;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;
/**
* @author Brad Lowe
*/
public class TestDevice { public class TestDevice {
private static final Logger LOG = LogUtils.getL7dLogger(TestDevice.class); private static final Logger LOG = LoggerFactory.getLogger(TestDevice.class);
public static String testCamera(OnvifCredentials creds) throws SOAPException, IOException { public static String testCamera(OnvifCredentials creds) throws SOAPException, IOException {
URL u = creds.getHost().startsWith("http") ? new URL(creds.getHost()) : new URL("http://" + creds.getHost()); URL u =
creds.getHost().startsWith("http")
? new URL(creds.getHost())
: new URL("http://" + creds.getHost());
return testCamera(u, creds.getUser(), creds.getPassword()); return testCamera(u, creds.getUser(), creds.getPassword());
} }
@@ -43,35 +46,32 @@ public class TestDevice {
public static String inspect(OnvifDevice device) { public static String inspect(OnvifDevice device) {
String out = ""; String out = "";
DeviceInfo info = device.getDeviceInfo(); DeviceInfo info = device.getDeviceInfo();
out += "DeviceInfo:" +sep + "\t" + info + sep; out += "DeviceInfo:" + sep + "\t" + info + sep;
DeviceServiceCapabilities caps = device.getDevice().getServiceCapabilities(); DeviceServiceCapabilities caps = device.getDevice().getServiceCapabilities();
out += "\tgetServiceCapabilities: " + OnvifUtils.format(caps) + sep; String sysCaps = OnvifUtils.format(caps);
out += "\tgetServiceCapabilities.getSystem: " + OnvifUtils.format(caps.getSystem()) + sep; sysCaps = sysCaps.replace("],", "],\t\n");
out += "\tgetServiceCapabilities: " + sysCaps + sep;
// out += "\tgetServiceCapabilities.getSystem: " + OnvifUtils.format(caps.getSystem()) + sep;
Media media = device.getMedia(); Media media = device.getMedia();
media.getVideoSources(); media.getVideoSources();
List<Profile> profiles = media.getProfiles(); List<Profile> profiles = media.getProfiles();
out += "Media Profiles: " + profiles.size() + sep; out += "Media Profiles: " + profiles.size() + sep;
for (Profile profile : profiles) { for (Profile profile : profiles) {
String profileToken = profile.getToken(); String profileToken = profile.getToken();
String rtsp = device.getRTSPUri(profileToken); String rtsp = device.getStreamUri(profileToken);
out += "\tProfile: " + profile.getName() + " token=" + profile.getToken() + sep; out += "\tProfile: " + profile.getName() + " token=" + profile.getToken() + sep;
out += "\t\trtsp: " + rtsp + sep; out += "\t\tstream: " + rtsp + sep;
out += "\t\tsnapshot: " + device.getSnapshotUri(profileToken) + sep; out += "\t\tsnapshot: " + device.getSnapshotUri(profileToken) + sep;
out += "\t\tdetails:" + OnvifUtils.format(profile) + sep; out += "\t\tdetails:" + OnvifUtils.format(profile) + sep;
} }
try {
List<VideoSource> videoSources = media.getVideoSources(); List<VideoSource> videoSources = media.getVideoSources();
out += "VideoSources: " + videoSources.size() + sep; out += "VideoSources: " + videoSources.size() + sep;
for (VideoSource v : videoSources) for (VideoSource v : videoSources) out += "\t" + OnvifUtils.format(v) + sep;
out += "\t" + OnvifUtils.format(v) + sep;
List<AudioSource> audioSources = media.getAudioSources();
out += "AudioSources: " + audioSources.size() + sep;
for (AudioSource a : audioSources)
out += "\t" + OnvifUtils.format(a) + sep;
ImagingPort imaging = device.getImaging(); ImagingPort imaging = device.getImaging();
if (imaging != null && videoSources.size() > 0) { if (imaging != null && videoSources.size() > 0) {
@@ -83,25 +83,41 @@ public class TestDevice {
out += "\tgetServiceCapabilities=" + OnvifUtils.format(image_caps) + sep; out += "\tgetServiceCapabilities=" + OnvifUtils.format(image_caps) + sep;
if (token != null) { if (token != null) {
out += "\tgetImagingSettings=" + OnvifUtils.format(imaging.getImagingSettings(token)) + sep; out +=
"\tgetImagingSettings="
+ OnvifUtils.format(imaging.getImagingSettings(token))
+ sep;
out += "\tgetMoveOptions=" + OnvifUtils.format(imaging.getMoveOptions(token)) + sep; out += "\tgetMoveOptions=" + OnvifUtils.format(imaging.getMoveOptions(token)) + sep;
out += "\tgetStatus=" + OnvifUtils.format(imaging.getStatus(token)) + sep; out += "\tgetStatus=" + OnvifUtils.format(imaging.getStatus(token)) + sep;
out += "\tgetOptions=" + OnvifUtils.format(imaging.getOptions(token)) + sep; out += "\tgetOptions=" + OnvifUtils.format(imaging.getOptions(token)) + sep;
} }
} catch (Throwable th) { } catch (Throwable th) {
out += "error=" + th.getMessage() + sep; out += "Imaging unavailable:" + th.getMessage() + sep;
} }
} }
} catch (Throwable th) {
// this can fail if the device doesn't support video sources.
out += "VideoSources: " + th.getMessage() + sep;
}
try {
// This may throw a SoapFaultException with the message "This device does not support audio"
List<AudioSource> audioSources = media.getAudioSources();
out += "AudioSources: " + audioSources.size() + sep;
for (AudioSource a : audioSources) out += "\t" + OnvifUtils.format(a) + sep;
} catch (Throwable th) {
out += "AudioSources Unavailable: " + th.getMessage() + sep;
}
try {
EventPortType events = device.getEvents(); EventPortType events = device.getEvents();
if (events != null) { if (events != null) {
out += "Events:" + sep; out += "Events:" + sep;
out += "\tgetServiceCapabilities=" + OnvifUtils.format(events.getServiceCapabilities()) + sep; out +=
"\tgetServiceCapabilities=" + OnvifUtils.format(events.getServiceCapabilities()) + sep;
GetEventProperties getEventProperties = new GetEventProperties(); GetEventProperties getEventProperties = new GetEventProperties();
GetEventPropertiesResponse getEventPropertiesResp = events.getEventProperties(getEventProperties); GetEventPropertiesResponse getEventPropertiesResp =
events.getEventProperties(getEventProperties);
out += "\tMessageContentFilterDialects:" + sep; out += "\tMessageContentFilterDialects:" + sep;
for (String f : getEventPropertiesResp.getMessageContentFilterDialect()) for (String f : getEventPropertiesResp.getMessageContentFilterDialect())
out += ("\t\t" + f + sep); out += ("\t\t" + f + sep);
@@ -117,17 +133,17 @@ public class TestDevice {
// WsNotificationTest.printTree(e, e.getNodeName()); // WsNotificationTest.printTree(e, e.getNodeName());
} }
out += tree; out += tree;
} }
} catch (Throwable th) {
out += "Events Unavailable: " + th.getMessage() + sep;
}
PTZ ptz = device.getPtz(); PTZ ptz = device.getPtz();
if (ptz != null) { if (ptz != null) {
out += "PTZ:" + sep;
String profileToken = profiles.get(0).getToken(); String profileToken = profiles.get(0).getToken();
try {
Capabilities ptz_caps = ptz.getServiceCapabilities(); Capabilities ptz_caps = ptz.getServiceCapabilities();
out += "PTZ:" + sep;
out += "\tgetServiceCapabilities=" + OnvifUtils.format(ptz_caps) + sep; out += "\tgetServiceCapabilities=" + OnvifUtils.format(ptz_caps) + sep;
PTZStatus s = ptz.getStatus(profileToken); PTZStatus s = ptz.getStatus(profileToken);
out += "\tgetStatus=" + OnvifUtils.format(s) + sep; out += "\tgetStatus=" + OnvifUtils.format(s) + sep;
@@ -135,12 +151,13 @@ public class TestDevice {
List<PTZPreset> presets = ptz.getPresets(profileToken); List<PTZPreset> presets = ptz.getPresets(profileToken);
if (presets != null && !presets.isEmpty()) { if (presets != null && !presets.isEmpty()) {
out += "\tPresets:" + presets.size() + sep; out += "\tPresets:" + presets.size() + sep;
for (PTZPreset p : presets) for (PTZPreset p : presets) out += "\t\t" + OnvifUtils.format(p) + sep;
out += "\t\t" + OnvifUtils.format(p) + sep; }
} catch (Throwable th) {
out += "PTZ: Unavailable" + th.getMessage() + sep;
} }
} }
return out; return out;
} }
@@ -153,26 +170,27 @@ public class TestDevice {
printTree(n, name + " - " + n.getNodeName(), buffer); printTree(n, name + " - " + n.getNodeName(), buffer);
} }
} else { } else {
buffer.append("\t\t"+ name + " - " + node.getNodeName() + "\n"); buffer.append("\t\t" + name + " - " + node.getNodeName() + "\n");
}
} }
} public static String testCamera(URL url, String user, String password)
throws SOAPException, IOException {
public static String testCamera(URL url, String user, String password) throws SOAPException, IOException { LOG.info("Testing camera:" + url);
OnvifDevice device = new OnvifDevice(url, user, password); OnvifDevice device = new OnvifDevice(url, user, password);
return inspect(device); return inspect(device);
} }
public static void main(String[] args) { public static void main(String[] args) {
try {
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args); OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
try {
// OnvifDevice.setVerbose(true);
String out = testCamera(creds); String out = testCamera(creds);
LOG.info("\n" + out + "\n"); LOG.info("\n" + out + "\n");
} catch (Throwable th) { } catch (Throwable th) {
LOG.warning("Error "+th); LOG.error("Failed for " + creds, th);
th.printStackTrace(); th.printStackTrace();
} }
} }
} }

View File

@@ -1,6 +1,15 @@
package org.onvif.client; package org.onvif.client;
import de.onvif.soap.OnvifDevice; import de.onvif.soap.OnvifDevice;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import javax.xml.bind.JAXBElement;
import javax.xml.soap.SOAPException;
import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.cxf.wsn.client.Consumer; import org.apache.cxf.wsn.client.Consumer;
@@ -11,10 +20,24 @@ import org.apache.cxf.wsn.services.JaxwsNotificationBroker;
import org.oasis_open.docs.wsn.b_2.FilterType; import org.oasis_open.docs.wsn.b_2.FilterType;
import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType; import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType;
import org.oasis_open.docs.wsn.b_2.TopicExpressionType; import org.oasis_open.docs.wsn.b_2.TopicExpressionType;
import org.oasis_open.docs.wsn.bw_2.*; import org.oasis_open.docs.wsn.bw_2.InvalidFilterFault;
import org.oasis_open.docs.wsn.bw_2.InvalidMessageContentExpressionFault;
import org.oasis_open.docs.wsn.bw_2.InvalidProducerPropertiesExpressionFault;
import org.oasis_open.docs.wsn.bw_2.InvalidTopicExpressionFault;
import org.oasis_open.docs.wsn.bw_2.NotifyMessageNotSupportedFault;
import org.oasis_open.docs.wsn.bw_2.SubscribeCreationFailedFault;
import org.oasis_open.docs.wsn.bw_2.TopicExpressionDialectUnknownFault;
import org.oasis_open.docs.wsn.bw_2.TopicNotSupportedFault;
import org.oasis_open.docs.wsn.bw_2.UnacceptableInitialTerminationTimeFault;
import org.oasis_open.docs.wsn.bw_2.UnrecognizedPolicyRequestFault;
import org.oasis_open.docs.wsn.bw_2.UnsupportedPolicyRequestFault;
import org.oasis_open.docs.wsrf.rw_2.ResourceUnknownFault; import org.oasis_open.docs.wsrf.rw_2.ResourceUnknownFault;
import org.onvif.ver10.events.wsdl.*; import org.onvif.ver10.events.wsdl.CreatePullPointSubscription;
import org.onvif.ver10.events.wsdl.CreatePullPointSubscription.SubscriptionPolicy; import org.onvif.ver10.events.wsdl.CreatePullPointSubscription.SubscriptionPolicy;
import org.onvif.ver10.events.wsdl.CreatePullPointSubscriptionResponse;
import org.onvif.ver10.events.wsdl.EventPortType;
import org.onvif.ver10.events.wsdl.GetEventProperties;
import org.onvif.ver10.events.wsdl.GetEventPropertiesResponse;
import org.onvif.ver10.schema.Capabilities; import org.onvif.ver10.schema.Capabilities;
import org.onvif.ver10.schema.CapabilityCategory; import org.onvif.ver10.schema.CapabilityCategory;
import org.onvif.ver10.schema.MediaUri; import org.onvif.ver10.schema.MediaUri;
@@ -23,23 +46,13 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import javax.xml.bind.JAXBElement;
import javax.xml.soap.SOAPException;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class WsNotificationTest { public class WsNotificationTest {
// This is a work in progress class...any help is welcome ;) // This is a work in progress class...any help is welcome ;)
// A good idea could be to follow this guide: // A good idea could be to follow this guide:
// https://access.redhat.com/documentation/en-us/red_hat_jboss_a-mq/6.1/html-single/ws-notification_guide/index#WSNTutorial // https://access.redhat.com/documentation/en-us/red_hat_jboss_a-mq/6.1/html-single/ws-notification_guide/index#WSNTutorial
public static void main(String args[]) throws IOException { public static void main(String[] args) throws IOException {
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args); OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
System.out.println("Connect to camera, please wait ..."); System.out.println("Connect to camera, please wait ...");
@@ -64,7 +77,8 @@ public class WsNotificationTest {
EventPortType eventWs = cam.getEvents(); EventPortType eventWs = cam.getEvents();
GetEventProperties getEventProperties = new GetEventProperties(); GetEventProperties getEventProperties = new GetEventProperties();
GetEventPropertiesResponse getEventPropertiesResp = eventWs.getEventProperties(getEventProperties); GetEventPropertiesResponse getEventPropertiesResp =
eventWs.getEventProperties(getEventProperties);
getEventPropertiesResp.getMessageContentFilterDialect().forEach(x -> System.out.println(x)); getEventPropertiesResp.getMessageContentFilterDialect().forEach(x -> System.out.println(x));
getEventPropertiesResp.getTopicExpressionDialect().forEach(x -> System.out.println(x)); getEventPropertiesResp.getTopicExpressionDialect().forEach(x -> System.out.println(x));
for (Object object : getEventPropertiesResp.getTopicSet().getAny()) { for (Object object : getEventPropertiesResp.getTopicSet().getAny()) {
@@ -72,30 +86,37 @@ public class WsNotificationTest {
printTree(e, e.getNodeName()); printTree(e, e.getNodeName());
} }
org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory(); org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory =
new org.oasis_open.docs.wsn.b_2.ObjectFactory();
CreatePullPointSubscription pullPointSubscription = new CreatePullPointSubscription(); CreatePullPointSubscription pullPointSubscription = new CreatePullPointSubscription();
FilterType filter = new FilterType(); FilterType filter = new FilterType();
TopicExpressionType topicExp = new TopicExpressionType(); TopicExpressionType topicExp = new TopicExpressionType();
topicExp.getContent().add("tns1:RuleEngine//.");// every event in that topicExp.getContent().add("tns1:RuleEngine//."); // every event in that
// topic // topic
topicExp.setDialect("http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet"); topicExp.setDialect("http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet");
JAXBElement<?> topicExpElem = objectFactory.createTopicExpression(topicExp); JAXBElement<?> topicExpElem = objectFactory.createTopicExpression(topicExp);
filter.getAny().add(topicExpElem); filter.getAny().add(topicExpElem);
pullPointSubscription.setFilter(filter); pullPointSubscription.setFilter(filter);
org.onvif.ver10.events.wsdl.ObjectFactory eventObjFactory = new org.onvif.ver10.events.wsdl.ObjectFactory(); org.onvif.ver10.events.wsdl.ObjectFactory eventObjFactory =
SubscriptionPolicy subcriptionPolicy = eventObjFactory.createCreatePullPointSubscriptionSubscriptionPolicy(); new org.onvif.ver10.events.wsdl.ObjectFactory();
SubscriptionPolicy subcriptionPolicy =
eventObjFactory.createCreatePullPointSubscriptionSubscriptionPolicy();
pullPointSubscription.setSubscriptionPolicy(subcriptionPolicy); pullPointSubscription.setSubscriptionPolicy(subcriptionPolicy);
String timespan = "PT10S";// every 10 seconds String timespan = "PT10S"; // every 10 seconds
// String timespan = "PT1M";//every 1 minute // String timespan = "PT1M";//every 1 minute
pullPointSubscription.setInitialTerminationTime(objectFactory.createSubscribeInitialTerminationTime(timespan)); pullPointSubscription.setInitialTerminationTime(
objectFactory.createSubscribeInitialTerminationTime(timespan));
try { try {
CreatePullPointSubscriptionResponse resp = eventWs.createPullPointSubscription(pullPointSubscription); CreatePullPointSubscriptionResponse resp =
eventWs.createPullPointSubscription(pullPointSubscription);
// Start a consumer that will listen for notification messages // Start a consumer that will listen for notification messages
// We'll just print the text content out for now. // We'll just print the text content out for now.
String eventConsumerAddress = "http://localhost:9001/MyConsumer"; String eventConsumerAddress = "http://localhost:9001/MyConsumer";
Consumer consumer = new Consumer(new Consumer.Callback() { Consumer consumer =
new Consumer(
new Consumer.Callback() {
public void notify(NotificationMessageHolderType message) { public void notify(NotificationMessageHolderType message) {
Object o = message.getMessage().getAny(); Object o = message.getMessage().getAny();
System.out.println(message.getMessage().getAny()); System.out.println(message.getMessage().getAny());
@@ -103,15 +124,17 @@ public class WsNotificationTest {
System.out.println(((Element) o).getTextContent()); System.out.println(((Element) o).getTextContent());
} }
} }
}, eventConsumerAddress); },
eventConsumerAddress);
String queuePort = "8182"; String queuePort = "8182";
String brokerPort = "8181"; String brokerPort = "8181";
String brokerAddress = "http://localhost:" + brokerPort + "/wsn/NotificationBroker"; String brokerAddress = "http://localhost:" + brokerPort + "/wsn/NotificationBroker";
ActiveMQConnectionFactory activemq = new ActiveMQConnectionFactory( ActiveMQConnectionFactory activemq =
new ActiveMQConnectionFactory(
"vm:(broker:(tcp://localhost:" + queuePort + ")?persistent=false)"); "vm:(broker:(tcp://localhost:" + queuePort + ")?persistent=false)");
JaxwsNotificationBroker notificationBrokerServer = new JaxwsNotificationBroker("WSNotificationBroker", JaxwsNotificationBroker notificationBrokerServer =
activemq); new JaxwsNotificationBroker("WSNotificationBroker", activemq);
notificationBrokerServer.setAddress(brokerAddress); notificationBrokerServer.setAddress(brokerAddress);
notificationBrokerServer.init(); notificationBrokerServer.init();
@@ -171,10 +194,17 @@ public class WsNotificationTest {
subscription.unsubscribe(); subscription.unsubscribe();
consumer.stop(); consumer.stop();
} catch (TopicNotSupportedFault | TopicExpressionDialectUnknownFault | InvalidTopicExpressionFault } catch (TopicNotSupportedFault
| InvalidMessageContentExpressionFault | InvalidProducerPropertiesExpressionFault | TopicExpressionDialectUnknownFault
| UnacceptableInitialTerminationTimeFault | NotifyMessageNotSupportedFault | ResourceUnknownFault | InvalidTopicExpressionFault
| UnsupportedPolicyRequestFault | InvalidFilterFault | SubscribeCreationFailedFault | InvalidMessageContentExpressionFault
| InvalidProducerPropertiesExpressionFault
| UnacceptableInitialTerminationTimeFault
| NotifyMessageNotSupportedFault
| ResourceUnknownFault
| UnsupportedPolicyRequestFault
| InvalidFilterFault
| SubscribeCreationFailedFault
| UnrecognizedPolicyRequestFault e) { | UnrecognizedPolicyRequestFault e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@@ -185,7 +215,6 @@ public class WsNotificationTest {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void printTree(Node node, String name) { public static void printTree(Node node, String name) {
@@ -195,8 +224,7 @@ public class WsNotificationTest {
Node n = nodes.item(i); Node n = nodes.item(i);
printTree(n, name + " - " + n.getNodeName()); printTree(n, name + " - " + n.getNodeName());
} }
} else } else System.out.println(name + " - " + node.getNodeName());
System.out.println(name + " - " + node.getNodeName());
} }
private static void takeScreenShot(String profileToken, OnvifDevice cam) { private static void takeScreenShot(String profileToken, OnvifDevice cam) {
@@ -222,8 +250,9 @@ public class WsNotificationTest {
List<Profile> profiles = cam.getMedia().getProfiles(); List<Profile> profiles = cam.getMedia().getProfiles();
for (Profile p : profiles) { for (Profile p : profiles) {
System.out.printf("Profile: [token=%s,name=%s,snapshotUri=%s]%n", p.getToken(), p.getName(), System.out.printf(
cam.getMedia().getSnapshotUri(p.getToken()).getUri()); "Profile: [token=%s,name=%s,snapshotUri=%s]%n",
p.getToken(), p.getName(), cam.getMedia().getSnapshotUri(p.getToken()).getUri());
} }
} }

View File

@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
@@ -83,10 +84,10 @@
<configuration> <configuration>
<wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot> <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>
<sourceRoot>${basedir}/src/main/java</sourceRoot> <sourceRoot>${basedir}/src/main/java</sourceRoot>
<!-- <!--
// TODO: Consider moving generated sources to separate folder and excluse from source control. // TODO: Consider moving generated sources to separate folder and excluse from source control.
<sourceRoot>${basedir}/generated/src/main/java</sourceRoot> <sourceRoot>${basedir}/generated/src/main/java</sourceRoot>
--> -->
<includes> <includes>
<include>*.wsdl</include> <include>*.wsdl</include>
</includes> </includes>
@@ -181,7 +182,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>
</plugins> </plugins>

View File

@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.onvif</groupId> <groupId>org.onvif</groupId>